lensref-0.1.0.5: References which can be joined and on which lenses can be applied

Safe HaskellNone
LanguageHaskell98

Data.LensRef

Contents

Synopsis

Core

References

class (MonadRefWriter (RefWriterSimple r), MonadRefReader (RefReaderSimple r), RefReader (RefReaderSimple r) ~ RefReaderSimple r) => RefClass r where Source

Type class for references which can be joined and on which lenses can be applied.

The join operation is join from Control.Monad: If (r :: RefReaderSimple r (RefSimple r a)) then (join r :: RefSimple r a). This is possible because reference operations work with (RefReaderSimple r (r a)) instead of just (r a). For more compact type signatures, (RefReaderSimple r (r a)) is called (RefSimple r a).

Associated Types

type RefReaderSimple r :: * -> * Source

Associated reference reader monad.

(RefReaderSimple m) is ismoroprhic to (Reader x) for some x. Laws which ensures this isomorphism ((r :: RefReaderSimple m a) is arbitrary):

r >> return ()  =  return ()
liftM2 (,) r r  =  liftM (\a -> (a, a)) r

See also http://stackoverflow.com/questions/16123588/what-is-this-special-functor-structure-called

Methods

unitRef :: RefSimple r () Source

unit reference

lensMap :: Lens' a b -> RefSimple r a -> RefSimple r b infixr 8 Source

Apply a lens on a reference.

readRefSimple :: RefSimple r a -> RefReaderSimple r a Source

Reference read.

writeRefSimple :: RefSimple r a -> a -> RefWriterSimple r () Source

Reference write.

type RefSimple r a = RefReaderSimple r (r a) Source

Reference wrapped into a RefReaderSimple monad. See the documentation of RefClass.

type RefWriterSimple m = RefWriterOf (RefReaderSimple m) Source

There are two associated types of a reference, RefReaderSimple and RefWriterSimple which determines each-other. This is implemented by putting only RefReaderSimple into the RefClass class and adding a RefWriterOf data family outside of RefClass.

RefWriterOf is hidden from the documentation because you never need it explicitly.

class Monad m => MonadRefReader m where Source

TODO

Minimal complete definition

liftRefReader

Associated Types

type BaseRef m :: * -> * Source

Base reference associated to the reference reader monad

Methods

liftRefReader :: RefReader m a -> m a Source

readRef :: (RefClass r, RefReader m ~ RefReaderSimple r) => RefSimple r a -> m a Source

readRef === liftRefReader . readRefSimple

class MonadRefReader m => MonadRefWriter m where Source

TODO

Minimal complete definition

liftRefWriter

Methods

liftRefWriter :: RefWriter m a -> m a Source

writeRef :: (RefClass r, RefReaderSimple r ~ RefReader m) => RefSimple r a -> a -> m () Source

writeRef r === liftRefWriter . writeRefSimple r

Reference creation

class (Monad m, RefClass (BaseRef m), MonadRefReader m, MonadMemo m) => MonadRefCreator m where Source

Monad for reference creation. Reference creation is not a method of the RefClass type class to make possible to create the same type of references in multiple monads.

For basic usage examples, look into the source of Data.LensRef.Test.

Minimal complete definition

extRef

Methods

extRef :: Ref m b -> Lens' a b -> a -> m (Ref m a) Source

Reference creation by extending the state of an existing reference.

Suppose that r is a reference and k is a lens.

Law 1: extRef applies k on r backwards, i.e. the result of (extRef r k a0) should behaves exactly as (lensMap k r).

(liftM (k .) $ extRef r k a0)  =  return r

Law 2: extRef does not change the value of r:

(extRef r k a0 >> readRef r)  =  readRef r

Law 3: Proper initialization of newly defined reference with a0:

(extRef r k a0 >>= readRef)  =  (readRef r >>= set k a0)

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

newRef extends the state s in an independent way.

newRef === extRef unitRef united

type Ref m a = RefSimple (BaseRef m) a Source

TODO

Dynamic networks

class (MonadRefCreator m, MonadRefWriter (Modifier m), MonadRefCreator (Modifier m), BaseRef (Modifier m) ~ BaseRef m, Monad (EffectM m), EffectM (Modifier m) ~ EffectM m, Modifier (Modifier m) ~ Modifier m) => MonadRegister m where Source

Monad for dynamic actions

Associated Types

type EffectM m :: * -> * Source

type Modifier m :: * -> * Source

Methods

onChange :: Eq a => RefReader m a -> (a -> m (m b)) -> m (RefReader m b) Source

onChangeSimple :: Eq a => RefReader m a -> (a -> m b) -> m (RefReader m b) Source

onRegionStatusChange :: (RegionStatusChange -> m ()) -> m () Source

liftEffectM :: EffectM m a -> m a Source

liftToModifier :: m a -> Modifier m a Source

registerCallback :: Functor f => f (Modifier m ()) -> m (f (EffectM m ())) Source

Other

class Monad m => MonadMemo m where Source

TODO

Methods

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

Lazy monadic evaluation. In case of y <- memoRead x, invoking y will invoke x at most once.

Laws:

  • (memoRead x >> return ()) === return ()

    • (memoRead x >>= id) === x
    • (memoRead x >>= y -> liftM2 (,) y y) === liftM (a -> (a, a)) y
    • (memoRead x >>= y -> liftM3 (,) y y y) === liftM (a -> (a, a, a)) y
    • ...

Instances

Derived constructs

modRef :: (MonadRefWriter m, RefClass r, RefReaderSimple r ~ RefReader m) => RefSimple r a -> (a -> a) -> m () Source

modRef r f === readRef r >>= writeRef r . f

class RefClass r => EqRefClass r where Source

Reference with inherent equivalence.

type EqRefSimple r a = RefReaderSimple r (EqRefCore r a) Source

RefClasss with inherent equivalence.

EqRefSimple r a === RefReaderSimple r (exist b . Eq b => (Lens' b a, r b))

As a reference, (m :: EqRefSimple r a) behaves as

join $ liftM (uncurry lensMap) m

type EqRef m a = EqRefSimple (BaseRef m) a Source

TODO

hasEffect :: EqRefClass r => RefSimple r a -> (a -> a) -> RefReaderSimple r Bool Source

hasEffect r f returns False iff (modRef m f) === (return ()).

hasEffect is correct only if toEqRef is applied on a pure reference (a reference which is a pure lens on the hidden state).

hasEffect makes defining auto-sensitive buttons easier, for example.

toEqRef :: (RefClass r, Eq a) => RefSimple r a -> EqRefSimple r a Source

EqRefSimple construction.

fromEqRef :: RefClass r => EqRefSimple r a -> RefSimple r a Source

An EqRefSimple is a normal reference if we forget about the equality.

fromEqRef m === join $ liftM (uncurry lensMap) m

newEqRef :: (MonadRefCreator m, Eq a) => a -> m (EqRef m a) Source

TODO