Safe Haskell | None |
---|
Original work available at: http:okmij.orgftpHgetellextensibleEff.hs. This module implements extensible effects as an alternative to monad transformers, as described in http:okmij.orgftpHgetellextensibleexteff.pdf.
Extensible Effects are implemented as typeclass constraints on an Eff[ect] datatype. A contrived example is:
- - Print a list of numbers, then print their sum. printAndSum :: (Member (Lift IO) e, Member State e) => [Integer] -> Eff e Integer printAndSum (x:xs) = do lift $ putStrLn $ show x onState (+ x) printAndSum [] = getState >>= lift . putStrLn
- data Eff r a
- class Member t r
- data a :> b
- run :: Eff Void w -> w
- send :: (forall w. (a -> VE w r) -> Union r (VE w r)) -> Eff r a
- admin :: Eff r w -> VE w r
- data Reader e v
- runReader :: Typeable e => Eff (Reader e :> r) w -> e -> Eff r w
- getReader :: Typeable e => Member (Reader e) r => Eff r e
- local :: (Typeable e, Member (Reader e) r) => (e -> e) -> Eff r a -> Eff r a
- data Trace v
- trace :: Member Trace r => String -> Eff r ()
- runTrace :: Eff (Trace :> Void) w -> IO w
- data Yield a v
- yield :: (Typeable a, Member (Yield a) r) => a -> Eff r ()
- runC :: Typeable a => Eff (Yield a :> r) w -> Eff r (Y r a)
- data Y r a
- data State s w
- getState :: Typeable e => Member (State e) r => Eff r e
- putState :: Typeable e => Member (State e) r => e -> Eff r ()
- onState :: (Typeable s, Member (State s) r) => (s -> s) -> Eff r ()
- runState :: Typeable s => s -> Eff (State s :> r) w -> Eff r (w, s)
- data Choose v
- choose :: Member Choose r => [a] -> Eff r a
- runChoice :: forall a r. Eff (Choose :> r) a -> Eff r [a]
- data Lift m v
- lift :: (Typeable1 m, Member (Lift m) r) => m a -> Eff r a
- runLift :: (Monad m, Typeable1 m) => Eff (Lift m :> Void) w -> m w
- data Exc e v
- throwError :: (Typeable e, Member (Exc e) r) => e -> Eff r a
- runError :: Typeable e => Eff (Exc e :> r) a -> Eff r (Either e a)
- catchError :: (Typeable e, Member (Exc e) r) => Eff r a -> (e -> Eff r a) -> Eff r a
- data Fresh i v
- fresh :: (Typeable i, Enum i, Member (Fresh i) r) => Eff r i
- runFresh :: (Typeable i, Enum i) => Eff (Fresh i :> r) w -> i -> Eff r w
- data CutFalse
- call :: Member Choose r => Eff (Exc CutFalse :> r) a -> Eff r a
- cutfalse :: Member (Exc CutFalse) r => Eff r a
Documentation
A sum data type, for composing
effects
In GHC 7.4, we should make it a list
(:>) :: (* -> *) -> (* -> List) -> List
The request for a value of type e from the current environment. This environment is analogous to a parameter of type e.
runReader :: Typeable e => Eff (Reader e :> r) w -> e -> Eff r wSource
The handler of Reader requests. The return type shows that all Reader requests are fully handled.
local :: (Typeable e, Member (Reader e) r) => (e -> e) -> Eff r a -> Eff r aSource
Locally rebind the value in the dynamic environment. This function both requests and admins Reader requests.
The yield request: reporting the value of type e and suspending the coroutine (For simplicity, a co-routine reports a value but accepts unit)
runC :: Typeable a => Eff (Yield a :> r) w -> Eff r (Y r a)Source
Launch a thread and report its status.
Status of a thread: done or reporting the value of the type a (For simplicity, a co-routine reports a value but accepts unit)
Strict state. Example: Implementing Fresh in terms of State but not revealing that fact. runFresh' :: (Typeable i, Enum i, Num i) => Eff (Fresh i :> r) w -> i -> Eff r w runFresh' m s = fst $ runState s (loop $ admin m) where loop (Val x) = return x loop (E u) = case decomp u of Right (Fresh k) -> do n <- getState putState (n + 1) loop (k n) Left u' -> send (k -> unsafeReUnion $ k $ u') >>= loop