-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An Alternative to Monad Transformers -- @package extensible-effects @version 1.9.1.0 -- | Original work at -- http://okmij.org/ftp/Haskell/extensible/OpenUnion1.hs and -- http://okmij.org/ftp/Haskell/extensible/OpenUnion2.hs. Open -- unions (type-indexed co-products) for extensible effects. -- -- TODO: see if we can do away with Typeable constraints, perhaps by -- incorporating ideas from -- http://okmij.org/ftp/Haskell/extensible/TList.hs module Data.OpenUnion -- | Class Member is defined only for the sake of the interface -- compatibility with OpenUnion1. Generally, the closed type family -- Member' below could be used instead. -- -- The Member t r specifies whether t is present -- anywhere in the sum type r, where t is some -- effectful type, e.g. Lift IO, -- State Int`. class Member' t r ~ True => Member (t :: * -> *) r -- | SetMember is similar to Member, but it allows types to -- belong to a "set". For every set, only one member can be in r -- at any given time. This allows us to specify exclusivity and -- uniqueness among arbitrary effects: -- --
--   -- Terminal effects (effects which must be run last)
--   data Terminal
--   
--   -- Make Lifts part of the Terminal effects set.
--   -- The fundep assures that there can only be one Terminal effect for any r.
--   instance Member (Lift m) r => SetMember Terminal (Lift m) r
--   
--   -- Only allow a single unique Lift effect, by making a "Lift" set.
--   instance Member (Lift m) r => SetMember Lift (Lift m) r
--   
class Member t r => SetMember set (t :: * -> *) r | r set -> t -- | Parameter r is phantom: it just tells what could be in the -- union. Where r is t1 :> t2 ... :> tn, -- Union r v can be constructed with a value of type -- ti v. Ideally, we should be able to add the constraint -- Member t r. -- -- NOTE: exposing the constructor below allows users to bypass the type -- system. See unsafeReUnion for example. data Union r v -- | A sum data type, for composing effects data (:>) (a :: * -> *) b -- | Construct a Union. inj :: (Functor t, Typeable t, Member t r) => t v -> Union r v -- | Try extracting the contents of a Union as a given type. prj :: (Typeable t, Member t r) => Union r v -> Maybe (t v) -- | Extract the contents of a Union as a given type. If the Union isn't of -- that type, a runtime error occurs. prjForce :: (Typeable t, Member t r) => Union r v -> (t v -> a) -> a -- | Try extracting the contents of a Union as a given type. If we can't, -- return a reduced Union that excludes the type we just checked. decomp :: Typeable t => Union (t :> r) v -> Either (Union r v) (t v) -- | Juggle types for a Union. Use cautiously. unsafeReUnion :: Union r w -> Union t w weaken :: (Typeable t, Functor t) => Union r w -> Union (t :> r) w instance Typeable Id instance MemberU set t r => SetMember set t r module Control.Monad.Free.Reflection -- | The abstract Free datatype. Original work available at -- http://okmij.org/ftp/Haskell/AlgorithmsH1.html#reflection-without-remorse. data Free f a -- | Inject a pure value into Free freePure :: a -> Free f a -- | Inject an impure value into Free freeImpure :: f (Free f a) -> Free f a -- | Case analysis for the Free construction. Similar in spirit to -- either and maybe. freeMap :: Functor f => (a -> t) -> (f (Free f a) -> t) -> Free f a -> t -- | The traditional view of Free constructions data FreeView f a -- | case embedding pure values Pure :: a -> FreeView f a -- | case embedding impure values nested in f. Traditionally this -- is the Control.Monad.Free.Free constructor, but that's -- confusing. Impure :: (f (Free f a)) -> FreeView f a -- | A way to get a Free construction from the view by constructing -- an explicit expression with one element. fromView :: FreeView f a -> Free f a -- | A way to evaluate the Free construction to its view (i.e., head -- normal form). This includes the logic to perform one level of monadic -- bind as needed from the FreeExp representation. toView :: Functor f => Free f a -> FreeView f a instance Typeable FreeView instance Typeable Free instance Functor f => Monad (Free f) instance Functor f => Applicative (Free f) instance Functor f => Functor (Free f) -- | Original work available at -- http://okmij.org/ftp/Haskell/extensible/Eff.hs. This module -- implements extensible effects as an alternative to monad transformers, -- as described in -- http://okmij.org/ftp/Haskell/extensible/exteff.pdf. -- -- Extensible Effects are implemented as typeclass constraints on an -- Eff[ect] datatype. A contrived example is: -- --
--   {-# LANGUAGE FlexibleContexts #-}
--   import Control.Eff
--   import Control.Eff.Lift
--   import Control.Eff.State
--   import Control.Monad (void)
--   import Data.Typeable
--   
--   -- Write the elements of a list of numbers, in order.
--   writeAll :: (Typeable a, Member (Writer a) e)
--            => [a]
--            -> Eff e ()
--   writeAll = mapM_ putWriter
--   
--   -- Add a list of numbers to the current state.
--   sumAll :: (Typeable a, Num a, Member (State a) e)
--          => [a]
--          -> Eff e ()
--   sumAll = mapM_ (onState . (+))
--   
--   -- Write a list of numbers and add them to the current state.
--   writeAndAdd :: (Member (Writer Integer) e, Member (State Integer) e)
--               => [Integer]
--               -> Eff e ()
--   writeAndAdd l = do
--       writeAll l
--       sumAll l
--   
--   -- Sum a list of numbers.
--   sumEff :: (Num a, Typeable a) => [a] -> a
--   sumEff l = let (s, ()) = run $ runState 0 $ sumAll l
--              in s
--   
--   -- Safely get the last element of a list.
--   -- Nothing for empty lists; Just the last element otherwise.
--   lastEff :: Typeable a => [a] -> Maybe a
--   lastEff l = let (a, ()) = run $ runWriter $ writeAll l
--               in a
--   
--   -- Get the last element and sum of a list
--   lastAndSum :: (Typeable a, Num a) => [a] -> (Maybe a, a)
--   lastAndSum l = let (lst, (total, ())) = run $ runWriter $ runState 0 $ writeAndAdd l
--                  in (lst, total)
--   
module Control.Eff -- | Basic type returned by all computations with extensible effects. The -- Eff r type is a type synonym where the type r -- is the type of effects that can be handled, and the missing type -- a (from the type application) is the type of value that is -- returned. -- -- Expressed another way: an Eff can either be a value (i.e., -- Pure case), or an effect of type Union r -- producing another Eff (i.e., Impure case). The result is -- that an Eff can produce an arbitrarily long chain of -- Union r effects, terminated with a pure value. -- -- As is made explicit below, the Eff type is simply the Free -- monad resulting from the Union r functor. -- --
--   type Eff r a = Free (Union r) a
--   
type Eff r = Free (Union r) -- | Class Member is defined only for the sake of the interface -- compatibility with OpenUnion1. Generally, the closed type family -- Member' below could be used instead. -- -- The Member t r specifies whether t is present -- anywhere in the sum type r, where t is some -- effectful type, e.g. Lift IO, -- State Int`. class Member' t r ~ True => Member (t :: * -> *) r -- | SetMember is similar to Member, but it allows types to -- belong to a "set". For every set, only one member can be in r -- at any given time. This allows us to specify exclusivity and -- uniqueness among arbitrary effects: -- --
--   -- Terminal effects (effects which must be run last)
--   data Terminal
--   
--   -- Make Lifts part of the Terminal effects set.
--   -- The fundep assures that there can only be one Terminal effect for any r.
--   instance Member (Lift m) r => SetMember Terminal (Lift m) r
--   
--   -- Only allow a single unique Lift effect, by making a "Lift" set.
--   instance Member (Lift m) r => SetMember Lift (Lift m) r
--   
class Member t r => SetMember set (t :: * -> *) r | r set -> t -- | Parameter r is phantom: it just tells what could be in the -- union. Where r is t1 :> t2 ... :> tn, -- Union r v can be constructed with a value of type -- ti v. Ideally, we should be able to add the constraint -- Member t r. -- -- NOTE: exposing the constructor below allows users to bypass the type -- system. See unsafeReUnion for example. data Union r v -- | A sum data type, for composing effects data (:>) (a :: * -> *) b -- | Construct a Union. inj :: (Functor t, Typeable t, Member t r) => t v -> Union r v -- | Try extracting the contents of a Union as a given type. prj :: (Typeable t, Member t r) => Union r v -> Maybe (t v) -- | Extract the contents of a Union as a given type. If the Union isn't of -- that type, a runtime error occurs. prjForce :: (Typeable t, Member t r) => Union r v -> (t v -> a) -> a -- | Try extracting the contents of a Union as a given type. If we can't, -- return a reduced Union that excludes the type we just checked. decomp :: Typeable t => Union (t :> r) v -> Either (Union r v) (t v) -- | Given a method of turning requests into results, we produce an -- effectful computation. send :: Union r a -> Eff r a -- | Get the result from a pure computation. run :: Eff Void w -> w -- | Given a request, either handle it or relay it. Both the handler and -- the relay can produce the same type of request that was handled. interpose :: (Typeable t, Functor t, Member t r) => Union r v -> (v -> Eff r a) -> (t v -> Eff r a) -> Eff r a -- | Given a request, either handle it or relay it. handleRelay :: Typeable t => Union (t :> r) v -> (v -> Eff r a) -> (t v -> Eff r a) -> Eff r a -- | Juggle types for a Union. Use cautiously. unsafeReUnion :: Union r w -> Union t w -- | Nondeterministic choice effect module Control.Eff.Choose -- | Nondeterministic choice data Choose v Choose :: [a] -> (a -> v) -> Choose v -- | choose lst non-deterministically chooses one value from the lst choose -- [] thus corresponds to failure choose :: Member Choose r => [a] -> Eff r a -- | Run a nondeterministic effect, returning all values. runChoice :: Eff (Choose :> r) a -> Eff r [a] -- | MonadPlus-like operators are expressible via choose mzero' :: Member Choose r => Eff r a -- | MonadPlus-like operators are expressible via choose mplus' :: Member Choose r => Eff r a -> Eff r a -> Eff r a instance Typeable Choose instance Functor Choose -- | Coroutines implemented with extensible effects module Control.Eff.Coroutine -- | The yield request: reporting a value of type e and suspending the -- coroutine. For readability, a coroutine accepts a unit to produce its -- value. data Yield a v Yield :: a -> (() -> v) -> Yield a v -- | Yield a value of type a and suspend the coroutine. yield :: (Typeable a, Member (Yield a) r) => a -> Eff r () -- | Launch a thread and report its status. runC :: Typeable a => Eff (Yield a :> r) w -> Eff r (Y r a w) -- | Status of a thread: done or reporting the value of the type a (For -- simplicity, a co-routine reports a value but accepts unit) -- -- Type parameter r is the effect we're yielding from. -- -- Type parameter a is the type that is yielded. -- -- Type parameter w is the type of the value returned from the -- coroutine when it has completed. data Y r a w Y :: a -> (() -> Eff r (Y r a w)) -> Y r a w Done :: w -> Y r a w instance Typeable Yield instance Functor (Yield a) -- | Lifting primitive Monad types to effectful computations. We only allow -- a single Lifted Monad because Monads aren't commutative (e.g. Maybe -- (IO a) is functionally distinct from IO (Maybe a)). module Control.Eff.Lift -- | Lift a Monad m to an effect. data Lift m v Lift :: (m a) -> (a -> v) -> Lift m v -- | Lift a Monad to an Effect. lift :: (Typeable m, SetMember Lift (Lift m) r) => m a -> Eff r a -- | The handler of Lift requests. It is meant to be terminal: we only -- allow a single Lifted Monad. runLift :: (Monad m, Typeable m) => Eff (Lift m :> ()) w -> m w instance Typeable Lift instance (MonadBase b m, Typeable m, SetMember Lift (Lift m) r) => MonadBase b (Eff r) instance (Typeable m, MonadIO m, SetMember Lift (Lift m) r) => MonadIO (Eff r) instance Functor (Lift m) -- | Exception-producing and exception-handling effects module Control.Eff.Exception -- | These are exceptions of the type e. This is akin to the error monad. newtype Exc e v Exc :: e -> Exc e v type Fail = Exc () -- | Throw an exception in an effectful computation. throwExc :: (Typeable e, Member (Exc e) r) => e -> Eff r a -- | Makes an effect fail, preventing future effects from happening. die :: Member Fail r => Eff r a -- | Run a computation that might produce an exception. runExc :: Typeable e => Eff (Exc e :> r) a -> Eff r (Either e a) -- | Runs a failable effect, such that failed computation return -- Nothing, and Just the return value on success. runFail :: Eff (Fail :> r) a -> Eff r (Maybe a) -- | Run a computation that might produce exceptions, and give it a way to -- deal with the exceptions that come up. catchExc :: (Typeable e, Member (Exc e) r) => Eff r a -> (e -> Eff r a) -> Eff r a -- | Add a default value (i.e. failure handler) to a fallible computation. -- This hides the fact that a failure happened. onFail :: Eff (Fail :> r) a -> Eff r a -> Eff r a -- | Run a computation until it produces an exception, and convert and -- throw that exception in a new context. rethrowExc :: (Typeable e, Typeable e', Member (Exc e') r) => (e -> e') -> Eff (Exc e :> r) a -> Eff r a -- | Treat Lefts as exceptions and Rights as return values. liftEither :: (Typeable e, Member (Exc e) r) => Either e a -> Eff r a -- | liftEither in a lifted Monad liftEitherM :: (Typeable m, Typeable e, Member (Exc e) r, SetMember Lift (Lift m) r) => m (Either e a) -> Eff r a -- | Lift a maybe into the Fail effect, causing failure if it's -- Nothing. liftMaybe :: Member Fail r => Maybe a -> Eff r a -- | Ignores a failure event. Since the event can fail, you cannot inspect -- its return type, because it has none on failure. To inspect it, use -- runFail. ignoreFail :: Eff (Fail :> r) a -> Eff r () instance Typeable Exc instance Functor (Exc e) -- | An example of non-trivial interaction of effects, handling of two -- effects together Non-determinism with control (cut) For the -- explanation of cut, see Section 5 of Hinze ICFP 2000 paper. Hinze -- suggests expressing cut in terms of cutfalse: -- --
--   = return () `mplus` cutfalse
--   where
--    cutfalse :: m a
--   
-- -- satisfies the following laws: -- --
--   cutfalse >>= k  = cutfalse              (F1)
--   cutfalse | m    = cutfalse              (F2)
--   
-- -- (note: m `mplus` cutfalse is different from -- cutfalse `mplus` m) In other words, cutfalse is the -- left zero of both bind and mplus. -- -- Hinze also introduces the operation call :: m a -> m -- a that delimits the effect of cut: call m -- executes m. If the cut is invoked in m, it discards only the choices -- made since m was called. Hinze postulates the axioms of call: -- --
--   call false = false                          (C1)
--   call (return a | m) = return a | call m     (C2)
--   call (m | cutfalse) = call m                (C3)
--   call (lift m >>= k) = lift m >>= (call . k) (C4)
--   
-- -- call m behaves like m except any cut inside -- m has only a local effect, he says. -- -- Hinze noted a problem with the "mechanical" derivation of backtracing -- monad transformer with cut: no axiom specifying the interaction of -- call with bind; no way to simplify nested invocations of call. -- -- We use exceptions for cutfalse Therefore, the law cutfalse -- >>= k = cutfalse is satisfied automatically since all -- exceptions have the above property. module Control.Eff.Cut data CutFalse CutFalse :: CutFalse -- | The interpreter -- it is like reify . reflect with a twist Compare -- this implementation with the huge implementation of call in Hinze 2000 -- (Figure 9) Each clause corresponds to the axiom of call or cutfalse. -- All axioms are covered. The code clearly expresses the intuition that -- call watches the choice points of its argument computation. When it -- encounteres a cutfalse request, it discards the remaining -- choicepoints. It completely handles CutFalse effects but not -- non-determinism. call :: Member Choose r => Eff (Exc CutFalse :> r) a -> Eff r a cutfalse :: Member (Exc CutFalse) r => Eff r a instance Typeable CutFalse -- | Create unique Enumerable values. module Control.Eff.Fresh -- | Create unique Enumerable values. newtype Fresh i v Fresh :: (i -> v) -> Fresh i v -- | Produce a value that has not been previously produced. fresh :: (Typeable i, Enum i, Member (Fresh i) r) => Eff r i -- | Run an effect requiring unique values. runFresh :: (Typeable i, Enum i) => Eff (Fresh i :> r) w -> i -> Eff r w instance Typeable Fresh instance Functor (Fresh i) -- | Lazy read-only state module Control.Eff.Reader.Lazy -- | The request for a value of type e from the current environment. This -- environment is analogous to a parameter of type e. newtype Reader e v Reader :: (e -> v) -> Reader e v -- | Get the current value from a Reader. ask :: (Typeable e, Member (Reader e) r) => Eff r e -- | Locally rebind the value in the dynamic environment. This function -- both requests and handles Reader requests. local :: (Typeable e, Member (Reader e) r) => (e -> e) -> Eff r a -> Eff r a -- | Request the environment value using a transformation function. reader :: (Typeable e, Member (Reader e) r) => (e -> a) -> Eff r a -- | The handler of Reader requests. The return type shows that all Reader -- requests are fully handled. runReader :: Typeable e => Eff (Reader e :> r) w -> e -> Eff r w instance Typeable Reader instance Functor (Reader e) -- | Strict read-only state module Control.Eff.Reader.Strict -- | The request for a value of type e from the current environment. This -- environment is analogous to a parameter of type e. newtype Reader e v Reader :: (e -> v) -> Reader e v -- | Get the current value from a Reader. ask :: (Typeable e, Member (Reader e) r) => Eff r e -- | Locally rebind the value in the dynamic environment. This function -- both requests and admins Reader requests. local :: (Typeable e, Member (Reader e) r) => (e -> e) -> Eff r a -> Eff r a -- | Request the environment value using a transformation function. reader :: (Typeable e, Member (Reader e) r) => (e -> a) -> Eff r a -- | The handler of Reader requests. The return type shows that all Reader -- requests are fully handled. runReader :: Typeable e => Eff (Reader e :> r) w -> e -> Eff r w instance Typeable Reader instance Functor (Reader e) -- | Lazy state effect module Control.Eff.State.Lazy -- | Strict state effect data State s w State :: (s -> s) -> (s -> w) -> State s w -- | Return the current value of the state. get :: (Typeable e, Member (State e) r) => Eff r e -- | Write a new value of the state. put :: (Typeable e, Member (State e) r) => e -> Eff r () -- | Transform the state with a function. modify :: (Typeable s, Member (State s) r) => (s -> s) -> Eff r () -- | Run a State effect. runState :: Typeable s => s -> Eff (State s :> r) w -> Eff r (s, w) -- | Run a State effect, discarding the final state. evalState :: Typeable s => s -> Eff (State s :> r) w -> Eff r w -- | Run a State effect and return the final state. execState :: Typeable s => s -> Eff (State s :> r) w -> Eff r s instance Typeable State instance Functor (State s) -- | Strict state effect -- -- Example: implementing Fresh -- --
--   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 <- get
--                         put (n + 1)
--                         loop (k n)
--       Left u' -> send (\k -> unsafeReUnion $ k <$> u') >>= loop
--   
module Control.Eff.State.Strict -- | Strict state effect data State s w State :: (s -> s) -> (s -> w) -> State s w -- | Return the current value of the state. get :: (Typeable e, Member (State e) r) => Eff r e -- | Write a new value of the state. put :: (Typeable e, Member (State e) r) => e -> Eff r () -- | Transform the state with a function. modify :: (Typeable s, Member (State s) r) => (s -> s) -> Eff r () -- | Run a State effect. runState :: Typeable s => s -> Eff (State s :> r) w -> Eff r (s, w) -- | Run a State effect, discarding the final state. evalState :: Typeable s => s -> Eff (State s :> r) w -> Eff r w -- | Run a State effect and return the final state. execState :: Typeable s => s -> Eff (State s :> r) w -> Eff r s instance Typeable State instance Functor (State s) -- | Lazy write-only state. module Control.Eff.Writer.Lazy -- | The request to remember a value of type w in the current environment data Writer w v Writer :: w -> v -> Writer w v -- | Write a new value. tell :: (Typeable w, Member (Writer w) r) => w -> Eff r () -- | Transform the state being produced. censor :: (Typeable w, Member (Writer w) r) => (w -> w) -> Eff r a -> Eff r a -- | Handle Writer requests, using a user-provided function to accumulate -- values. runWriter :: Typeable w => (w -> b -> b) -> b -> Eff (Writer w :> r) a -> Eff r (b, a) -- | Handle Writer requests by taking the first value provided. runFirstWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a) -- | Handle Writer requests by overwriting previous values. runLastWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a) -- | Handle Writer requests, using a Monoid instance to accumulate values. runMonoidWriter :: (Monoid w, Typeable w) => Eff (Writer w :> r) a -> Eff r (w, a) instance Typeable Writer instance Functor (Writer w) -- | Strict write-only state. module Control.Eff.Writer.Strict -- | The request to remember a value of type w in the current environment data Writer w v Writer :: !w -> v -> Writer w v -- | Write a new value. tell :: (Typeable w, Member (Writer w) r) => w -> Eff r () -- | Transform the state being produced. censor :: (Typeable w, Member (Writer w) r) => (w -> w) -> Eff r a -> Eff r a -- | Handle Writer requests, using a user-provided function to accumulate -- values. runWriter :: Typeable w => (w -> b -> b) -> b -> Eff (Writer w :> r) a -> Eff r (b, a) -- | Handle Writer requests by taking the first value provided. runFirstWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a) -- | Handle Writer requests by overwriting previous values. runLastWriter :: Typeable w => Eff (Writer w :> r) a -> Eff r (Maybe w, a) -- | Handle Writer requests, using a Monoid instance to accumulate values. runMonoidWriter :: (Monoid w, Typeable w) => Eff (Writer w :> r) a -> Eff r (w, a) instance Typeable Writer instance Functor (Writer w) -- | A Trace effect for debugging module Control.Eff.Trace -- | Trace effect for debugging data Trace v Trace :: String -> (() -> v) -> Trace v -- | Print a string as a trace. trace :: Member Trace r => String -> Eff r () -- | Run a computation producing Traces. runTrace :: Eff (Trace :> ()) w -> IO w instance Typeable Trace instance Functor Trace -- | Operational Monad (https://wiki.haskell.org/Operational) -- implemented with extensible effects. module Control.Eff.Operational -- | Lift values to an effect. You can think this is a generalization of -- Lift. data Program instr v Program :: (instr a) -> (a -> v) -> Program instr v -- | Lift a value to a monad. singleton :: (Typeable instr, Member (Program instr) r) => instr a -> Eff r a -- | Convert values using given interpreter to effects. runProgram :: Typeable f => (forall x. f x -> Eff r x) -> Eff (Program f :> r) a -> Eff r a instance Typeable Program instance Functor (Program instr) module Control.Eff.Operational.Example -- | Define data using GADTs. data Jail a Print :: String -> Jail () Scan :: Jail String prog :: Member (Program Jail) r => Eff r () -- | Then, implements interpreters from the data to effects. adventIO :: (Member (Lift IO) r, SetMember Lift (Lift IO) r) => Jail a -> Eff r a adventPure :: (Member (Writer String) r, Member (State [String]) r) => Jail a -> Eff r a instance Typeable Jail