module Air.Data.Record.SimpleLabel
(
Getter
, Setter
, Modifier
, Point
, (:->) (Label)
, label
, get, set, mod
, getM, setM, modM
, (=:)
)
where
import Prelude hiding ((.), id, mod)
import Control.Applicative
import Control.Category
import Control.Monad.State hiding (get)
type Getter s x = s -> x
type Setter s x = x -> s -> s
type Modifier s x = (x -> x) -> s -> s
data Point s x = Point
{ _get :: Getter s x
, _set :: Setter s x
}
_mod :: Point s x -> (x -> x) -> s -> s
_mod l f a = _set l (f (_get l a)) a
newtype (s :-> x) = Label { unLabel :: Point s x }
label :: Getter s x -> Setter s x -> s :-> x
label g s = Label (Point g s)
get :: (s :-> x) -> s -> x
get = _get . unLabel
set :: (s :-> x) -> x -> s -> s
set = _set . unLabel
mod :: (s :-> x) -> (x -> x) -> s -> s
mod = _mod . unLabel
instance Category (:->) where
id = Label (Point id const)
(Label a) . (Label b) = Label (Point (_get a . _get b) (_mod b . _set a))
getM :: MonadState s m => s :-> b -> m b
getM = gets . get
setM :: MonadState s m => s :-> b -> b -> m ()
setM l = modify . set l
infixr 7 =:
(=:) :: MonadState s m => s :-> b -> b -> m ()
(=:) = setM
modM :: MonadState s m => s :-> b -> (b -> b) -> m ()
modM l = modify . mod l