lgtk-0.3.2: lens-based GUI with Gtk backend

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.

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.

Instances

Monad m => Category (MLens m) 

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

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

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 creation

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 given in Data.MLens.Ref.

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 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 as r.
  • 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.

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

Pure lenses, built 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, built 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

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

Impure (but effect-free) lens constuctor, built on lensStore.

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

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

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