-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An Alternative to Monad Transformers -- -- This package introduces datatypes for typeclass-constrained effects, -- as an alternative to monad-transformer based (datatype-constrained) -- approach of multi-layered effects. For more information, see the -- original paper at -- http://okmij.org/ftp/Haskell/extensible/exteff.pdf. Any help is -- appreciated! @package extensible-effects @version 1.11.0.2 module Data.OpenUnion.Imports type Member = MemberImpl OU2 type MemberU = MemberUImpl OU2 -- | 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 type Member = MemberImpl OU2 -- | 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 forall (k :: BOX) (set :: k -> * -> *) (t :: * -> *) r. Data.OpenUnion.Imports.MemberU set t r => Data.OpenUnion.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 GHC.Base.Functor f => GHC.Base.Functor (Control.Monad.Free.Reflection.Free f) instance GHC.Base.Functor f => GHC.Base.Applicative (Control.Monad.Free.Reflection.Free f) instance GHC.Base.Functor f => GHC.Base.Monad (Control.Monad.Free.Reflection.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 can be found under -- Control.Eff.Example. To run the effects, consult the tests. 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) type Member = MemberImpl OU2 -- | 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 GHC.Base.Functor Control.Eff.Choose.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 GHC.Base.Functor (Control.Eff.Coroutine.Yield a) -- | 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 GHC.Base.Functor (Control.Eff.State.Lazy.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 GHC.Base.Functor (Control.Eff.Writer.Lazy.Writer w) -- | Example usage of Control.Eff module Control.Eff.Example -- | Write the elements of a list of numbers, in order. writeAll :: (Typeable a, Member (Writer a) e) => [a] -> Eff e () -- | Add a list of numbers to the current state. sumAll :: (Typeable a, Num a, Member (State a) e) => [a] -> Eff e () -- | Write a list of numbers and add them to the current state. writeAndAdd :: (Member (Writer a) e, Member (State a) e, Num a, Typeable a) => [a] -> Eff e () -- | Sum a list of numbers. sumEff :: (Num a, Typeable a) => [a] -> a -- | Safely get the last element of a list. Nothing for empty lists; Just -- the last element otherwise. lastEff :: Typeable a => [a] -> Maybe a -- | Get the last element and sum of a list lastAndSum :: (Typeable a, Num a) => [a] -> (Maybe a, 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 :> Void) w -> m w instance GHC.Base.Functor (Control.Eff.Lift.Lift m) instance (Data.Typeable.Internal.Typeable m, Control.Monad.IO.Class.MonadIO m, Data.OpenUnion.SetMember Control.Eff.Lift.Lift (Control.Eff.Lift.Lift m) r) => Control.Monad.IO.Class.MonadIO (Control.Eff.Eff r) instance (Control.Monad.Base.MonadBase b m, Data.Typeable.Internal.Typeable m, Data.OpenUnion.SetMember Control.Eff.Lift.Lift (Control.Eff.Lift.Lift m) r) => Control.Monad.Base.MonadBase b (Control.Eff.Eff r) -- | 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 GHC.Base.Functor (Control.Eff.Exception.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 -- | 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 GHC.Base.Functor (Control.Eff.Fresh.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 GHC.Base.Functor (Control.Eff.Reader.Lazy.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 GHC.Base.Functor (Control.Eff.Reader.Strict.Reader e) -- | 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 GHC.Base.Functor (Control.Eff.State.Strict.State s) -- | 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 GHC.Base.Functor (Control.Eff.Writer.Strict.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 :> Void) w -> IO w instance GHC.Base.Functor Control.Eff.Trace.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 GHC.Base.Functor (Control.Eff.Operational.Program instr) -- | Example usage of Control.Eff.Operational. 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