-- | The multi-parameter type-class 'View' provides an abstraction @View v n@ of a type @n@ that exposes a value of type (@v@). It allows both to 'inspect' and 'update' the value, while hiding the internal structure of the value type (@n@).
module Data.View where
-- | Minimal complete definition: @inspect@ and one of {@update@, @adjust@}
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
-- | convenience function that can be used to access record fields of the exposed type
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