extensible-effects- An Alternative to Monad Transformers

Safe HaskellSafe



On-demand state computation: example taken from Edward Kmett's comment here: http://www.reddit.com/r/haskell/comments/387ex0/are_extensible_effects_a_complete_replacement_for/crt1pzm

Extensible effects make it clear that where the computation is delayed and they do maintain the degree of extensibility (the delayed computation must be effect-closed, but the whole computation does not have to be).



data LazyState s v where Source #

Define a new effect for state on-demand (in ExtEff, the state is by default strict -- as it should be if we want the predictable performance and effect sequencing)


LGet :: LazyState s s 
LPut :: s -> LazyState s () 
Delay :: Eff '[LazyState s] a -> LazyState s a 

lget :: Member (LazyState s) r => Eff r s Source #

Primitive state operations

lput :: Member (LazyState s) r => s -> Eff r () Source #

lmodify :: (Member (LazyState s) r, Member (LazyState t) r) => (t -> s) -> Eff r () Source #

onDemand :: Member (LazyState s) r => Eff '[LazyState s] v -> Eff r v Source #

runStateLazy :: s -> Eff (LazyState s ': r) a -> Eff r (a, s) Source #

The handler

runStateBack0 :: Eff '[LazyState s] a -> (a, s) Source #

Backwards state The overall state is represented with two attributes: the inherited getAttr and the synthesized putAttr. At the root node, putAttr becomes getAttr, tying the knot. As usual, the inherited attribute is the argument (i.e., the environment) and the synthesized is the result of the handler |go| below.

runStateBack :: Eff '[LazyState s] a -> (a, s) Source #

Another implementation, exploring Haskell's laziness to make putAttr also technically inherited, to accumulate the sequence of updates. This implementation is compatible with deep handlers, and lets us play with different notions of backwardness