module Data.View where
class View v n where
inspect ∷ n → v
update ∷ v → n → n
adjust ∷ (v → v) → n → n
update v = adjust (const v)
adjust f n = update (f $ inspect n) n
instance View n n where
inspect = id
update = const
instance (View v1 n, View v2 n) ⇒ View (v1,v2) n where
inspect n = (inspect n, inspect n)
update (v1,v2) = update v1 . update v2
instance (View v1 n, View v2 n, View v3 n) ⇒ View (v1,v2,v3) n where
inspect n = (inspect n, inspect n, inspect n)
update (v1,v2,v3) = update v1 . update v2 . update v3
instance (View v1 n, View v2 n, View v3 n, View v4 n) ⇒ View (v1,v2,v3,v4) n where
inspect n = (inspect n, inspect n, inspect n, inspect n)
update (v1,v2,v3,v4) = update v1 . update v2 . update v3 . update v4
examine ∷ View v n ⇒ (v → field) → n → field
examine field = field . inspect
adjustM ∷ (Monad m, View v n) ⇒ (v → m v) → n → m n
adjustM f n = do
n' ← f $ inspect n
return $ update n' n