Safe Haskell | None |
---|
The main monadic lens interface, ideally users should import only this module.
- data MLens m a b
- type Lens a b = MLens Identity a b
- type Ref m a = MLens m Unit a
- getL :: Monad m => MLens m a b -> a -> m b
- setL :: Monad m => MLens m a b -> b -> a -> m a
- modL :: Monad m => MLens m b a -> (a -> a) -> b -> m b
- fromLens :: Monad m => Lens a b -> MLens m a b
- toLens :: (forall m. Monad m => MLens m a b) -> Lens a b
- mapMLens :: (Monad m, Monad n) => Morph m n -> MLens m a b -> MLens n a b
- (.) :: Category cat => forall b c a. cat b c -> cat a b -> cat a c
- (***) :: Monad m => MLens m a b -> MLens m c d -> MLens m (a, c) (b, d)
- joinML :: Monad m => (a -> m (MLens m a b)) -> MLens m a b
- joinLens :: Monad m => MLens m a (MLens m a b) -> MLens m a b
- memoMLens :: (NewRef m, Eq a, Eq b) => MLens m a b -> m (MLens m a b)
- id :: Category cat => forall a. cat a a
- unitLens :: Monad m => MLens m a ()
- fstLens :: Monad m => MLens m (a, b) a
- sndLens :: Monad m => MLens m (a, b) b
- maybeLens :: Monad m => MLens m (Bool, a) (Maybe a)
- listLens :: Monad m => MLens m (Bool, (a, [a])) [a]
- ithLens :: Monad m => Int -> MLens m [a] a
- lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a b
- forkLens :: (Monoid a, Monad m) => MLens m a (a, a)
- justLens :: Monad m => a -> MLens m (Maybe a) a
- showLens :: (Monad m, Show a, Read a) => MLens m a String
- readRef :: Monad m => MLens m Unit a -> m a
- writeRef :: Monad m => Ref m a -> a -> m ()
- modRef :: Monad m => Ref m a -> (a -> a) -> m ()
- class Monad m => NewRef m where
- class NewRef m => ExtRef m where
- data Ext i m a
- runExt :: Monad m => (forall i. Ext i m a) -> m a
- runExt_ :: forall c m. (Functor m, NewRef m) => (forall n. (Monad n, Functor n) => Morph m n -> Morph n m -> c n -> c m) -> (forall i. c (Ext i m)) -> m (c m)
- undoTr :: ExtRef m => (a -> a -> Bool) -> Ref m a -> m (m (Maybe (m ())), m (Maybe (m ())))
- type Morph m n = forall a. m a -> n a
- memoRead :: NewRef m => m a -> m (m a)
- memoWrite :: (NewRef m, Eq b) => (b -> m a) -> m (b -> m a)
Data types
Monadic lenses.
The following representations would be also good for (MLens m a b)
:
a -> m (Store b (m a))
forall f . Functor f => (b -> m (f (m b))) -> a -> m (f (m a))
(a -> m b, b -> a -> m a)
The last representation has no efficient composition operation (the set operation on composition of n lenses use O(n * n) get operations with the last representation).
Using lenses which do not fulfil the lens laws are safe, but one should take extra care when doing program transformations or reasoning about code with impure lenses.
The following law is a minimum, but some lenses (which do logging) do not fulfil this:
- get-no-effect:
(getL k a >> return ())
===(return ())
TODO: List laws, document which laws hold for each lenses.
type Lens a b = MLens Identity a bSource
Side-effect free lenses.
The following representations would be also good for (Lens a b)
:
forall m . Monad m => MLens m a b
Laws for pure monadic lenses:
- set-get:
(setL l b a >>= getL l)
===(setL l b a >> return b)
- get-set:
(getL l a >>= b -> setL l b a)
===(return a)
- set-set:
(setL l b a >>= setL l b')
===(setL l b' a)
For example, fstLens
and (fstLens . fstLens)
fulfil these laws.
type Ref m a = MLens m Unit aSource
Note that references lenses can be composed with lenses. For example, if
r :: Ref m (a,b)
then
fstLens . r :: Ref m a
Reference laws for pure references:
-
(readRef r >> return ())
===(return ())
-
(readRef r >>= writeRef r)
===(return ())
-
(writeRef r a >> readRef r)
===(return a)
-
(writeRef r a >> writeRef r a')
===(writeRef r a')
These laws are equivalent to the get-no-effect, set-get, get-set and set-set laws for monadic lenses.
Lens operations
Lens transformations
(***) :: Monad m => MLens m a b -> MLens m c d -> MLens m (a, c) (b, d)Source
Tensor product
could be defined as
instance Monad m => Tensor (MLens m)
Tensor
is defined in Control.Category.Product in the data-lens package.
joinLens :: Monad m => MLens m a (MLens m a b) -> MLens m a bSource
It would be possible to define a Monad
instance for (MLens m a)
too, but monad laws would not hold.
Pure lenses
Impure lenses
lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a bSource
Impure (but effect-free) lens constuctor
Reference operations
class Monad m => NewRef m whereSource
Laws for NewRef
:
- Any reference created by
newRef
should satisfy the reference laws given in Data.MLens.Ref.
class NewRef m => ExtRef m whereSource
Suppose that k
is a pure lens, and
s <- extRef r k a0
.
The following laws should hold:
-
s
is a pure reference. -
(k . s)
behaves exactly asr
. - The initial value of
s
is the result of(readRef r >>= setL k a0)
.
Moreover, (extRef r k a0)
should not change the value of r
.
The following two operations should be identical:
newRew x
extRef unitLens unitLens x
For examples, see Control.MLens.ExtRef.Pure.Test.
runExt_ :: forall c m. (Functor m, NewRef m) => (forall n. (Monad n, Functor n) => Morph m n -> Morph n m -> c n -> c m) -> (forall i. c (Ext i m)) -> m (c m)Source
Advanced running of the (Ext i m)
monad.
Functor
in contexts would not be needed if it were a superclass of Monad
.
:: ExtRef m | |
=> (a -> a -> Bool) | equality on state |
-> Ref m a | reference of state |
-> m (m (Maybe (m ())), m (Maybe (m ()))) | undo and redo actions |
Undo-redo state transformation