lgtk-0.4: lens-based API for Gtk

Safe HaskellNone

Control.MLens

Contents

Description

The main monadic lens interface, ideally users should import only this module.

Synopsis

Data types

data MLens m a b Source

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.

Instances

Monad m => Category (MLens m) 

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

mapMLens :: (Monad m, Monad n) => Morph m n -> MLens m a b -> MLens n a bSource

(.) :: Category cat => forall b c a. cat b c -> cat a b -> cat a c

morphism composition

(***) :: 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.

joinML :: Monad m => (a -> m (MLens m a b)) -> MLens m a bSource

memoMLens :: (NewRef m, Eq a, Eq b) => MLens m a b -> m (MLens m a b)Source

Memoise pure lenses

Lens destruction

runMLens :: MLens m a b -> a -> m (b, b -> m a)Source

runRef :: Monad m => Ref m a -> m (a, a -> m ())Source

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 newRef should satisfy the reference laws.

Methods

newRef :: a -> m (Ref m a)Source

Instances

NewRef IO

Note that this instance does not fulfil the NewRef laws in a multi-threaded environment.

(NewRef m, Monoid w) => NewRef (WriterT w m) 
Monad m => NewRef (Ext i m) 

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:

  • s is 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.

Methods

extRef :: Ref m b -> MLens m a b -> a -> m (Ref m a)Source

Instances

Monad m => ExtRef (Ext i m) 

data Ext i m a Source

Instances

MonadWriter w m => MonadWriter w (Ext i m) 
MonadTrans (Ext i) 
Monad m => Monad (Ext i m) 
Functor m => Functor (Ext i m) 
Monad m => NewRef (Ext i m) 
Monad m => ExtRef (Ext i m) 

runExt :: Monad m => (forall i. Ext i m a) -> m aSource

Basic running of the (Ext i m) monad.

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

getL :: Monad m => MLens m a b -> a -> m bSource

setL :: Monad m => MLens m a b -> b -> a -> m aSource

modL :: Monad m => MLens m b a -> (a -> a) -> b -> m bSource

readRef :: Monad m => Ref m a -> m aSource

writeRef :: Monad m => Ref m a -> a -> m ()Source

modRef :: Monad m => Ref m a -> (a -> a) -> m ()Source

Pure lenses, defined with lensStore

id :: Category cat => forall a. cat a a

the identity morphism

unitLens :: Monad m => MLens m a ()Source

fstLens :: Monad m => MLens m (a, b) aSource

sndLens :: Monad m => MLens m (a, b) bSource

maybeLens :: Monad m => MLens m (Bool, a) (Maybe a)Source

listLens :: Monad m => MLens m (Bool, (a, [a])) [a]Source

ithLens :: Monad m => Int -> MLens m [a] aSource

ithLens is pure only with proper preconditions.

Impure lenses, defined with lensStore

forkLens :: (Monoid a, Monad m) => MLens m a (a, a)Source

justLens :: Monad m => a -> MLens m (Maybe a) aSource

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

fromLens :: Monad m => Lens a b -> MLens m a bSource

toLens :: (forall m. Monad m => MLens m a b) -> Lens a bSource

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.

undoTrSource

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

memoRead :: NewRef m => m a -> m (m a)Source

memoWrite :: (NewRef m, Eq b) => (b -> m a) -> m (b -> m a)Source

Auxiliary definitions

type Morph m n = forall a. m a -> n aSource

Consistency tests

testExt :: [String]Source

Consistency tests for Ext, should give an empty list of errors.