| Safe Haskell | None |
|---|
Control.MLens
Contents
Description
The main monadic lens interface, ideally users should import only this module.
- data MLens m a b
- type Ref m a = MLens m Unit a
- 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
- memoMLens :: (NewRef m, Eq a, Eq b) => MLens m a b -> m (MLens m a b)
- runMLens :: MLens m a b -> a -> m (b, b -> m a)
- runRef :: Monad m => Ref m a -> m (a, a -> m ())
- lensStore :: Monad m => (a -> (b, b -> a)) -> MLens m a b
- 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)
- 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
- readRef :: Monad m => Ref m a -> m a
- writeRef :: Monad m => Ref m a -> a -> m ()
- modRef :: Monad m => Ref m a -> (a -> a) -> m ()
- 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
- 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
- type Lens a b = MLens Identity a b
- fromLens :: Monad m => Lens a b -> MLens m a b
- toLens :: (forall m. Monad m => MLens m a b) -> Lens a b
- lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a b
- joinLens :: Monad m => MLens m a (MLens m a b) -> MLens m a b
- undoTr :: ExtRef m => (a -> a -> Bool) -> Ref m a -> m (m (Maybe (m ())), m (Maybe (m ())))
- memoRead :: NewRef m => m a -> m (m a)
- memoWrite :: (NewRef m, Eq b) => (b -> m a) -> m (b -> m a)
- type Morph m n = forall a. m a -> n a
- testExt :: [String]
Data types
Monadic lenses.
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.
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 Ref m a = MLens m Unit aSource
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.
Reference lenses can be composed with lenses. For example, if
r :: Ref m (a,b)
then
fstLens . r :: Ref m a
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.
Lens destruction
Lens construction
lensStore :: Monad m => (a -> (b, b -> a)) -> MLens m a bSource
Impure (but effect-free) lens constuctor
class Monad m => NewRef m whereSource
Laws for NewRef:
- Any reference created by
newRefshould satisfy the reference laws.
class NewRef m => ExtRef m whereSource
Suppose that r is a pure reference and k is a pure lens.
The following laws should hold:
-
(extRef r k a0 >>= readRef)===(readRef r >>= setL k a0) -
(extRef r k a0 >> readRef r)===(readRef r)
Given s <- extRef r k a0, the following laws should hold:
-
sis a pure reference -
(k . s)===r
Law for newRef when extRef is defined:
-
(newRew x)===(extRef unitLens unitLens x)
For basic usage examples, look into the source of 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.
Derived constructs
Lens operations
Pure lenses, defined with lensStore
Impure lenses, defined with lensStore
Other derived construts
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
lens :: Monad m => (a -> b) -> (b -> a -> a) -> MLens m a bSource
Impure (but effect-free) lens constuctor, defined with lensStore.
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.
Arguments
| :: 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