{-# LANGUAGE UnicodeSyntax, MultiParamTypeClasses, FlexibleInstances #-}
module Data.View where
class View v n where
inspect ∷ n → v
update ∷ v → n → n
adjust ∷ (v → v) → n → n
update v
v = forall v n. View v n => (v -> v) -> n -> n
adjust (forall a b. a -> b -> a
const v
v)
adjust v -> v
f n
n = forall v n. View v n => v -> n -> n
update (v -> v
f forall a b. (a -> b) -> a -> b
$ forall v n. View v n => n -> v
inspect n
n) n
n
instance View n n where
inspect :: n -> n
inspect = forall n. n -> n
id
update :: n -> n -> n
update = forall a b. a -> b -> a
const
instance (View v1 n, View v2 n) ⇒ View (v1,v2) n where
inspect :: n -> (v1, v2)
inspect n
n = (forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n)
update :: (v1, v2) -> n -> n
update (v1
v1,v2
v2) = forall v n. View v n => v -> n -> n
update v1
v1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v2
v2
instance (View v1 n, View v2 n, View v3 n) ⇒ View (v1,v2,v3) n where
inspect :: n -> (v1, v2, v3)
inspect n
n = (forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n)
update :: (v1, v2, v3) -> n -> n
update (v1
v1,v2
v2,v3
v3) = forall v n. View v n => v -> n -> n
update v1
v1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v2
v2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v3
v3
instance (View v1 n, View v2 n, View v3 n, View v4 n) ⇒ View (v1,v2,v3,v4) n where
inspect :: n -> (v1, v2, v3, v4)
inspect n
n = (forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n, forall v n. View v n => n -> v
inspect n
n)
update :: (v1, v2, v3, v4) -> n -> n
update (v1
v1,v2
v2,v3
v3,v4
v4) = forall v n. View v n => v -> n -> n
update v1
v1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v2
v2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v3
v3 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => v -> n -> n
update v4
v4
examine ∷ View v n ⇒ (v → field) → n → field
examine :: forall v n field. View v n => (v -> field) -> n -> field
examine v -> field
field = v -> field
field forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall v n. View v n => n -> v
inspect
adjustM ∷ (Monad m, View v n) ⇒ (v → m v) → n → m n
adjustM :: forall (m :: * -> *) v n.
(Monad m, View v n) =>
(v -> m v) -> n -> m n
adjustM v -> m v
f n
n = do
v
n' ← v -> m v
f forall a b. (a -> b) -> a -> b
$ forall v n. View v n => n -> v
inspect n
n
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall v n. View v n => v -> n -> n
update v
n' n
n