-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A simple effect system that integrates with MTL -- -- Please see the tutorial modules @package simple-effects @version 0.10.0.2 module Control.Effects.Generic data M a class (Generic (a m), Generic (a (t m)), Generic (a M)) => SimpleMethods a m t liftSimple :: SimpleMethods a m t => a m -> a (t m) class ProductOfSimpleMethods p pM m t where { type family LiftedProducts p pM m t :: * -> *; } liftProducts :: ProductOfSimpleMethods p pM m t => Proxy m -> Proxy t -> Proxy pM -> p x -> LiftedProducts p pM m t x class (MonadTrans t, Monad m) => SimpleMethod f fM (m :: * -> *) (t :: (* -> *) -> * -> *) where { type family LiftedMethod f fM m t; } liftMethod :: SimpleMethod f fM m t => Proxy m -> Proxy t -> Proxy fM -> f -> LiftedMethod f fM m t class IndependentOfM (a :: k) (m :: * -> *) genericLiftThrough :: forall t e em m. (MonadTrans t, Monad m, Monad (t m), SimpleMethods (em e) m t) => em e m -> em e (t m) class MonadicMethods a m mergeMonadicMethods :: MonadicMethods a m => m (a m) -> a m class ProductOfMonadicMethods p pM a m mergeMonadicProducts :: ProductOfMonadicMethods p pM a m => Proxy p -> Proxy pM -> m (a m) -> (a m -> p x) -> p x class Monad m => MonadicMethod a f fM m mergeMethod :: MonadicMethod a f fM m => Proxy fM -> (a m -> f) -> m (a m) -> f genericMergeContext :: MonadicMethods a m => m (a m) -> a m instance Control.Effects.Generic.MonadicMethod a f fM m => Control.Effects.Generic.ProductOfMonadicMethods (GHC.Generics.S1 m1 (GHC.Generics.Rec0 f)) (GHC.Generics.S1 m1 (GHC.Generics.Rec0 fM)) a m instance (b ~ m x, GHC.Base.Monad m) => Control.Effects.Generic.MonadicMethod a b (Control.Effects.Generic.M x) m instance (f ~ (b -> c), GHC.Base.Monad m, Control.Effects.Generic.MonadicMethod a c cM m) => Control.Effects.Generic.MonadicMethod a f (bM -> cM) m instance forall k (m :: * -> *) (a :: (* -> *) -> *) f (fM :: k). ((TypeError ...), GHC.Base.Monad m) => Control.Effects.Generic.MonadicMethod a f fM m instance (GHC.Generics.Rep (a m) ~ GHC.Generics.D1 m1 (GHC.Generics.C1 m2 p), GHC.Generics.Rep (a Control.Effects.Generic.M) ~ GHC.Generics.D1 m1 (GHC.Generics.C1 m2 pM), Control.Effects.Generic.ProductOfMonadicMethods p pM a m, GHC.Generics.Generic (a m), GHC.Generics.Generic (a Control.Effects.Generic.M)) => Control.Effects.Generic.MonadicMethods a m instance forall k1 k2 (f1 :: k2 -> *) (f1M :: k1 -> *) (a :: (* -> *) -> *) (m :: * -> *) (f2 :: k2 -> *) (f2M :: k1 -> *). (Control.Effects.Generic.ProductOfMonadicMethods f1 f1M a m, Control.Effects.Generic.ProductOfMonadicMethods f2 f2M a m) => Control.Effects.Generic.ProductOfMonadicMethods (f1 GHC.Generics.:*: f2) (f1M GHC.Generics.:*: f2M) a m instance (f ~ (a -> b), Control.Effects.Generic.SimpleMethod b bM m t, Control.Effects.Generic.IndependentOfM a m) => Control.Effects.Generic.SimpleMethod f (a -> bM) m t instance forall k1 k2 (a :: k1 -> k2) (m :: * -> *) (b :: k1). (Control.Effects.Generic.IndependentOfM a m, Control.Effects.Generic.IndependentOfM b m) => Control.Effects.Generic.IndependentOfM (a b) m instance (TypeError ...) => Control.Effects.Generic.IndependentOfM Control.Effects.Generic.M m instance forall k (a :: k) (m :: * -> *). Control.Effects.Generic.IndependentOfM a m instance Control.Effects.Generic.SimpleMethod f fM m t => Control.Effects.Generic.ProductOfSimpleMethods (GHC.Generics.S1 m1 (GHC.Generics.Rec0 f)) (GHC.Generics.S1 m1 (GHC.Generics.Rec0 fM)) m t instance (Control.Monad.Trans.Class.MonadTrans t, GHC.Base.Monad m, a ~ m x) => Control.Effects.Generic.SimpleMethod a (Control.Effects.Generic.M x) m t instance forall k (m :: * -> *) (t :: (* -> *) -> * -> *) a (b :: k). ((TypeError ...), GHC.Base.Monad m, Control.Monad.Trans.Class.MonadTrans t) => Control.Effects.Generic.SimpleMethod a b m t instance forall k (a :: (k -> *) -> *) (m :: k -> *) (m1 :: GHC.Generics.Meta) (m2 :: GHC.Generics.Meta) (p :: * -> *) (pM :: * -> *) (t :: (k -> *) -> k -> *). (GHC.Generics.Rep (a m) ~ GHC.Generics.D1 m1 (GHC.Generics.C1 m2 p), GHC.Generics.Rep (a Control.Effects.Generic.M) ~ GHC.Generics.D1 m1 (GHC.Generics.C1 m2 pM), GHC.Generics.Rep (a (t m)) ~ GHC.Generics.D1 m1 (GHC.Generics.C1 m2 (Control.Effects.Generic.LiftedProducts p pM m t)), Control.Effects.Generic.ProductOfSimpleMethods p pM m t, GHC.Generics.Generic (a m), GHC.Generics.Generic (a (t m)), GHC.Generics.Generic (a Control.Effects.Generic.M)) => Control.Effects.Generic.SimpleMethods a m t instance forall k1 k2 k3 (f1 :: * -> *) (f1M :: k3 -> *) (m :: k2) (t :: k1) (f2 :: * -> *) (f2M :: k3 -> *). (Control.Effects.Generic.ProductOfSimpleMethods f1 f1M m t, Control.Effects.Generic.ProductOfSimpleMethods f2 f2M m t) => Control.Effects.Generic.ProductOfSimpleMethods (f1 GHC.Generics.:*: f2) (f1M GHC.Generics.:*: f2M) m t module Control.Monad.Runnable -- | A class of monads that have a run function. -- -- The runMonad function gives the result inside of IO. The only -- reason for this is to allow an instance for IO to be written. Other -- instances do not perform any aditional IO. -- -- Instances for Identity, IO and (Runnable m, -- RunnableTrans t, Monad (t m)) => Runnable (t -- m) are given so users should only provide additional -- RunnableTrans instances instead of Runnable ones. class Monad m => Runnable m where { type family MonadicState m :: *; type family MonadicResult m a :: *; } -- | Get the current state value. currentMonadicState :: Runnable m => m (MonadicState m) -- | If given a result, reconstruct a monadic compitation. restoreMonadicState :: Runnable m => MonadicResult m a -> m a -- | Given the required state value and a computation, run the computation -- up to the IO effect. This should effectively run each layer in the -- transformer stack. The MonadicState should hold all the needed -- information to do so. -- -- A more formal description of what it means to run a transformer is -- given for the runTransformer function. runMonad :: Runnable m => MonadicState m -> m a -> IO (MonadicResult m a) -- | Given the required state value and a computation, run the computation -- up to the IO effect. This should effectively run each layer in the -- transformer stack. The MonadicState should hold all the needed -- information to do so. -- -- A more formal description of what it means to run a transformer is -- given for the runTransformer function. runMonad :: (Runnable m, PureRunnable m) => MonadicState m -> m a -> IO (MonadicResult m a) class Runnable m => PureRunnable m runPureMonad :: PureRunnable m => MonadicState m -> m a -> MonadicResult m a -- | A class of transformers that can run their effects in the underlying -- monad. -- -- The following laws need to hold. -- --
--   \t -> do st <- currentTransState
--            res <- lift (runTransformer t st)
--            restoreTransState res
--   == id
--   
-- --
--   f :: (forall a. m a -> m a)
--   \m s -> runTransformer (lift (f m)) s == \m s -> f (runTransformer (lift m) s)
--   
class MonadTrans t => RunnableTrans t where { type family TransformerState t (m :: * -> *) :: *; type family TransformerResult t (m :: * -> *) a :: *; } -- | Get the current state value. currentTransState :: (RunnableTrans t, Monad m) => t m (TransformerState t m) -- | If given a result, reconstruct the computation. restoreTransState :: (RunnableTrans t, Monad m) => TransformerResult t m a -> t m a -- | Given the required state value and a computation, run the effects of -- the transformer in the underlying monad. runTransformer :: (RunnableTrans t, Monad m) => t m a -> TransformerState t m -> m (TransformerResult t m a) instance (Control.Monad.Runnable.Runnable m, Control.Monad.Runnable.RunnableTrans t, GHC.Base.Monad (t m)) => Control.Monad.Runnable.Runnable (t m) instance (Control.Monad.Runnable.PureRunnable m, Control.Monad.Runnable.RunnableTrans t, GHC.Base.Monad (t m)) => Control.Monad.Runnable.PureRunnable (t m) instance Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.State.Strict.StateT s) instance Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.State.Lazy.StateT s) instance GHC.Base.Monoid s => Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.Writer.Strict.WriterT s) instance GHC.Base.Monoid s => Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.Writer.Lazy.WriterT s) instance Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.Reader.ReaderT s) instance GHC.Base.Monoid w => Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.RWS.Strict.RWST r w s) instance GHC.Base.Monoid w => Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.RWS.Lazy.RWST r w s) instance Control.Monad.Runnable.RunnableTrans Control.Monad.Trans.Identity.IdentityT instance Control.Monad.Trans.Error.Error e => Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.Error.ErrorT e) instance Control.Monad.Runnable.RunnableTrans (Control.Monad.Trans.Except.ExceptT e) instance Control.Monad.Runnable.RunnableTrans Control.Monad.Trans.Maybe.MaybeT instance Control.Monad.Runnable.RunnableTrans ListT.ListT instance Control.Monad.Runnable.Runnable Data.Functor.Identity.Identity instance Control.Monad.Runnable.PureRunnable Data.Functor.Identity.Identity instance Control.Monad.Runnable.Runnable GHC.Types.IO module Control.Effects class Effect e where { data family EffMethods e (m :: * -> *) :: *; type family CanLift e (t :: (* -> *) -> * -> *) :: Constraint; type CanLift e t = MonadTrans t; } liftThrough :: forall t m. (Effect e, CanLift e t, Monad m, Monad (t m)) => EffMethods e m -> EffMethods e (t m) liftThrough :: forall t m. (Effect e, Generic (EffMethods e m), MonadTrans t, Monad m, Monad (t m), SimpleMethods (EffMethods e) m t) => EffMethods e m -> EffMethods e (t m) mergeContext :: (Effect e, Monad m) => m (EffMethods e m) -> EffMethods e m mergeContext :: (Effect e, Generic (EffMethods e m), MonadicMethods (EffMethods e) m) => m (EffMethods e m) -> EffMethods e m class (Effect e, Monad m) => MonadEffect e m effect :: MonadEffect e m => EffMethods e m newtype RuntimeImplemented e m a RuntimeImplemented :: ReaderT (EffMethods e m) m a -> RuntimeImplemented e m a [getRuntimeImplemented] :: RuntimeImplemented e m a -> ReaderT (EffMethods e m) m a implement :: forall e m a. EffMethods e m -> RuntimeImplemented e m a -> m a instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Random.Class.MonadRandom m => Control.Monad.Random.Class.MonadRandom (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Control.Effects.RuntimeImplemented e m) instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Effects.RuntimeImplemented e m) instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Control.Effects.RuntimeImplemented e m) instance GHC.Base.Alternative m => GHC.Base.Alternative (Control.Effects.RuntimeImplemented e m) instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Control.Effects.RuntimeImplemented e m) instance GHC.Base.Monad m => GHC.Base.Monad (Control.Effects.RuntimeImplemented e m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Effects.RuntimeImplemented e m) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Trans.Class.MonadTrans (Control.Effects.RuntimeImplemented e) instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Effects.RuntimeImplemented e m) instance Control.Monad.Runnable.RunnableTrans (Control.Effects.RuntimeImplemented e) instance (Control.Effects.Effect e, GHC.Base.Monad m, Control.Effects.CanLift e (Control.Effects.RuntimeImplemented e)) => Control.Effects.MonadEffect e (Control.Effects.RuntimeImplemented e m) instance (Control.Effects.MonadEffect e m, GHC.Base.Monad (t m), Control.Effects.CanLift e t) => Control.Effects.MonadEffect e (t m) -- | The MonadState you know and love with some differences. First, -- there's no functional dependency limiting your stack to a single state -- type. This means less type inference so it might not be enough to just -- write getState. Write 'getState @MyStateType' instead using -- TypeApplications. -- -- Second, the functions have less generic names and are called -- getState and setState. -- -- Third, since it's a part of this effect framework, you get an -- implement function with which you can provide a different state -- implementation _at runtime_. module Control.Effects.State data State s -- | Get current value of the state with the type s. You can use -- type applications to tell the type checker which type of state you -- want. getState @Int getState :: forall s m. MonadEffect (State s) m => m s -- | Set a new value for the state of type s You can use type -- applications to tell the type checker which type of state you're -- setting. setState @Int 5 setState :: forall s m. MonadEffect (State s) m => s -> m () -- | Transform the state of type s using the given function. You -- can use type applications to tell the type checker which type of state -- you're modifying. modifyState @Int (+ 1) modifyState :: forall s m. MonadEffect (State s) m => (s -> s) -> m () -- | Implement the state effect via the StateT transformer. If you have a -- function with a type like f :: MonadEffect (State Int) m => m -- () you can use implementStateViaStateT to satisfy the -- MonadEffect constraint. -- --
--   implementStateViaStateT @Int 0 f :: Monad m => m ()
--   
implementStateViaStateT :: forall s m a. Monad m => s -> StateT s m a -> m a -- | Handle the state requirement using an IORef. If you have a -- function with a type like f :: MonadEffect (State Int) m => m -- () you can use implementStateViaIORef to replace the -- MonadEffect constraint with MonadIO. This is convenient -- if you already have a MonadIO constraint and you don't want to -- use the StateT transformer for some reason. -- --
--   implementStateViaIORef @Int 0 f :: MonadIO m => m ()
--   
implementStateViaIORef :: forall s m a. MonadIO m => s -> RuntimeImplemented (State s) m a -> m a instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.State.State s) m) instance Control.Effects.Effect (Control.Effects.State.State s) instance GHC.Base.Monad m => Control.Effects.MonadEffect (Control.Effects.State.State s) (Control.Monad.Trans.State.Lazy.StateT s m) module Control.Effects.Parallel forkThread :: IO () -> IO (MVar ()) appendState :: forall s m a proxy. (Semigroup s, MonadEffect (State s) m) => proxy s -> m a -> m a parallelWithRestore :: forall m a. Runnable m => (m a -> m a) -> [m a] -> m [a] parallelWithSequence :: Runnable m => [m a] -> m [a] parallel :: forall m a. Runnable m => [m a] -> m [MonadicResult m a] -- | This effect allows you to "throw" a signal. For the most part signals -- are the same as checked exceptions. The difference here is that the -- handler has the option to provide the value that will be the result -- of calling the signal function. This effectively allows -- you to have recoverable exceptions at the throw site, instead of just -- at the handling site. module Control.Effects.Signal -- | The handle function will return a value of this type. data ResumeOrBreak b c -- | Give a value to the caller of signal and keep going. Resume :: b -> ResumeOrBreak b c -- | Continue the execution after the handler. The handler will return this -- value Break :: c -> ResumeOrBreak b c data Signal a b -- | Throw a signal with no possible recovery. The handler is forced to -- only return the Break constructor because it cannot construct a -- Void value. -- -- If this function is used along with handleAsException, this -- module behaves like regular checked exceptions. throwSignal :: MonadEffect (Throw a) m => a -> m b -- | Handle signals of a computation. The handler function has the option -- to provide a value to the caller of signal and continue -- execution there, or do what regular exception handlers do and continue -- execution after the handler. handleSignal :: forall a b c m. Monad m => (a -> m (ResumeOrBreak b c)) -> RuntimeImplemented (Signal a b) (ExceptT c m) c -> m c type Throw e = Signal e Void -- | This handler can only behave like a regular exception handler. If used -- along with throwSignal this module behaves like regular checked -- exceptions. handleException :: forall a c m. Monad m => (a -> m c) -> ExceptT a m c -> m c -- | See documentation for handleException. This handler gives you -- an Either. handleToEither :: forall e a m. ExceptT e m a -> m (Either e a) -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the Maybe monad. -- -- Computations are actions that may produce a value or exit. -- -- The return function yields a computation that produces that -- value, while >>= sequences two subcomputations, exiting -- if either computation does. newtype MaybeT (m :: * -> *) a :: (* -> *) -> * -> * MaybeT :: m Maybe a -> MaybeT a [runMaybeT] :: MaybeT a -> m Maybe a -- | Discard all the Throw and Signal effects. If any -- exception was thrown the result will be Nothing. discardAllExceptions :: MaybeT m a -> m (Maybe a) -- | Satisfies all the Throw and Signal constraints if -- they all throw Showable exceptions. The first thrown exception -- will be shown and returned as a Left result. showAllExceptions :: Functor m => ExceptT SomeSignal m a -> m (Either Text a) data HandleException e -- | Use this function to handle exceptions without discarding the -- Throw effect. You'll want to use this if you're writing a -- recursive function. Using the regular handlers in that case will -- result with infinite types. -- -- Since this function doesn't discard constraints, you still need to -- handle the exception on the whole computation. -- -- Here's a slightly contrived example. -- --
--   data NotFound = NotFound
--   data Tree a = Leaf a | Node (Tree a) (Tree a)
--   data Step = GoLeft | GoRight
--   findIndex :: (Handles NotFound m, Eq a) => a -> Tree a -> m [Step]
--   findIndex x (Leaf a) | x == a    = return []
--                        | otherwise = throwSignal NotFound
--   findIndex x (Node l r) = ((GoLeft :) $ findIndex x l)
--       & handleWithoutDiscarding (NotFound -> (GoRight :) $ findIndex x r)
--   
-- -- Note: When you finally handle the exception effect, the order in which -- you handle it and other effects determines whether -- handleWithoutDiscarding rolls back other effects if an -- exception occured or it preserves all of them up to the point of the -- exception. Handling exceptions last and handling them first will -- produce the former and latter behaviour respectively. handleWithoutDiscarding :: forall e m a. MonadEffect (HandleException e) m => (e -> m a) -> m a -> m a -- | handleToEither that doesn't discard Throws -- constraints. See documentation for handleWithoutDiscarding. handleToEitherRecursive :: MonadEffect (HandleException e) m => m a -> m (Either e a) data SomeSignal signal :: forall a b m. MonadEffect (Signal a b) m => a -> m b instance GHC.Show.Show Control.Effects.Signal.SomeSignal instance GHC.Read.Read Control.Effects.Signal.SomeSignal instance GHC.Classes.Ord Control.Effects.Signal.SomeSignal instance GHC.Classes.Eq Control.Effects.Signal.SomeSignal instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Signal.Signal a b) m) instance Control.Effects.Effect (Control.Effects.Signal.HandleException e) instance GHC.Base.Monad m => Control.Effects.MonadEffect (Control.Effects.Signal.HandleException e) (Control.Monad.Trans.Except.ExceptT e m) instance (TypeError ...) => Control.Effects.MonadEffect (Control.Effects.Signal.Signal a b) GHC.Types.IO instance (GHC.Show.Show e, GHC.Base.Monad m) => Control.Effects.MonadEffect (Control.Effects.Signal.Signal e b) (Control.Monad.Trans.Except.ExceptT Control.Effects.Signal.SomeSignal m) instance Control.Effects.Effect (Control.Effects.Signal.Signal a b) instance GHC.Base.Monad m => Control.Effects.MonadEffect (Control.Effects.Signal.Signal e b) (Control.Monad.Trans.Except.ExceptT e m) instance GHC.Base.Monad m => Control.Effects.MonadEffect (Control.Effects.Signal.Signal a b) (Control.Monad.Trans.Maybe.MaybeT m) instance (GHC.Base.Monad m, b ~ c) => Control.Effects.MonadEffect (Control.Effects.Signal.Signal a c) (Control.Effects.RuntimeImplemented (Control.Effects.Signal.Signal a b) m) -- | The regular old MonadReader effect with some differences. -- First, there's no functional dependency limiting your stack to a -- single environment type. This means less type inference so it might -- not be enough to just write readEnv. Write 'readEnv @MyEnvType' -- instead using TypeApplications. -- -- Second, the function has a less generic name and is called -- readEnv. -- -- Third, since it's a part of this effect framework, you get a -- implementReadEnv function with which you can provide a -- different environment implementation _at runtime_. module Control.Effects.Reader data ReadEnv e -- | Read a value of type e. Use with the TypeApplications -- extension to help with type inference readEnv @Int readEnv :: forall e m. MonadEffect (ReadEnv e) m => m e -- | Use the given action in the underlying monad to provide environment -- values. You can think of implementReadEnv x m as replacing -- all readEnv calls in m with x. implementReadEnv :: Functor m => m e -> RuntimeImplemented (ReadEnv e) m a -> m a instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Reader.ReadEnv e) m) instance Control.Effects.Effect (Control.Effects.Reader.ReadEnv e) -- | Add non-determinism to your monad. Uses the ListT transformer -- under the hood. module Control.Effects.List data NonDeterminism -- | Get a value from the list. The choice of which value to take is -- non-deterministic in a sense that the rest of the computation will be -- ran once for each of them. choose :: forall a m. MonadEffect NonDeterminism m => [a] -> m a -- | Signals that this branch of execution failed to produce a result. deadEnd :: MonadEffect NonDeterminism m => m a -- | Execute all the effects and collect the result in a list. Note that -- this forces all the results, no matter which elements of the result -- list you end up actually using. For lazyer behavior use the other -- handlers. evaluateToList :: Monad m => ListT m a -> m [a] -- | Given a function, apply it to all the results. traverseAllResults :: Monad m => (a -> m ()) -> ListT m a -> m () -- | Given a folding function, fold over every result. If you want to -- terminate eary, use the foldWithEarlyTermination instead. foldAllResults :: Monad m => (r -> a -> m r) -> r -> ListT m a -> m r -- | Same as foldAllResults but the folding function has the ability -- to terminate early by returning Nothing. foldWithEarlyTermination :: Monad m => (r -> a -> m (Maybe r)) -> r -> ListT m a -> m r -- | Executes only the effects needed to produce the first n results. evaluateNResults :: Monad m => Int -> ListT m a -> m [a] -- | Executes only the effects needed to produce a single result. evaluateOneResult :: Monad m => ListT m a -> m (Maybe a) -- | Execute all the effects but discard their results. evaluateAll :: Monad m => ListT m a -> m () instance Control.Effects.Effect Control.Effects.List.NonDeterminism instance GHC.Base.Monad m => Control.Effects.MonadEffect Control.Effects.List.NonDeterminism (ListT.ListT m) -- | A neat effect that you can use to get early returns in your functions. -- Here's how to use it. -- -- Before: -- --
--   f = do
--       m1 <- maybeFunc1
--       case m1 of
--           Nothing -> return "1 nothing"
--           Just x -> do
--               m2 <- maybeFunc2
--               case m2 of
--                   Nothing -> return "2 nothing"
--                   Just y -> return (x <> y)
--   
-- -- After: -- --
--   f = handleEarly $ do
--       m1 <- maybeFunc1
--       x <- ifNothingEarlyReturn "1 nothing" m1
--       m2 <- maybeFunc2
--       y <- ifNothingEarlyReturn "2 nothing" m2
--       return (x <> y)
--   
-- -- You can use the earlyReturn function directly, or one of the -- helpers for common use cases. module Control.Effects.Early data Early a -- | Allows you to return early from a function. Make sure you -- handleEarly to get the actual result out. earlyReturn :: forall a b m. MonadEffect (Early a) m => a -> m b -- | Get the result from a computation. Either the early returned one, or -- the regular result. handleEarly :: Monad m => ExceptT (EarlyValue a) m a -> m a -- | Only do the given action and exit early with it's result. onlyDo :: MonadEffect (Early a) m => m a -> m b -- | Early return the given value if the Maybe is Nothing. -- Otherwise, contnue with the value inside of it. ifNothingEarlyReturn :: MonadEffect (Early a) m => a -> Maybe b -> m b -- | Only do the given action and early return with it's result if the -- given value is Nothing. Otherwise continue with the value -- inside of the Maybe. ifNothingDo :: MonadEffect (Early a) m => m a -> Maybe b -> m b -- | If the value is a Left, get the value, process it and early -- return the result. Otherwise just return the Right value. ifLeftEarlyReturn :: MonadEffect (Early c) m => (a -> c) -> Either a b -> m b -- | If the value is a Left, get the value, process it and only do -- the resulting action. Otherwise just return the Right value. ifLeftDo :: MonadEffect (Early c) m => (a -> m c) -> Either a b -> m b instance Control.Effects.Effect (Control.Effects.Early.Early a) instance (GHC.Base.Monad m, a ~ b) => Control.Effects.MonadEffect (Control.Effects.Early.Early a) (Control.Monad.Trans.Except.ExceptT (Control.Effects.Early.EarlyValue b) m) -- | The Async effect allows you to fork new threads in monads other -- than just IO. module Control.Effects.Async -- | The name of the effect data Async -- | The type that represents the forked computation in the monad -- m that eventually computes a value of type a. -- Depending on the monad, the computation may produce zero, one or even -- multiple values of that type. newtype AsyncThread m a AsyncThread :: (Async (m a)) -> AsyncThread m a -- | The IO implementation uses the async library. -- | Fork a new thread to run the given computation. The monadic context is -- forked into the new thread. -- -- For example, if we use state, the current state value will be visible -- int he forked computation. Depending on how we ultimately implement -- the state, modifying it may or may not be visible from the main -- thread. If we use implementStateViaStateT then setting the -- state in the forked thread will just modify the thread-local value. On -- the other hand, if we use implementStateViaIORef then both the -- main thread and the new thread will use the same reference meaning -- they can interact through it. async :: MonadEffect Async m => m a -> m (AsyncThread m a) -- | Wait for the thread to finish and return it's result. The monadic -- context will also be merged. -- -- Example: -- --
--   setState @Int 1
--   th <- async $ do
--       setState @Int 2
--   waitAsync th
--   print =<< getState @Int -- Outputs 2
--   
waitAsync :: MonadEffect Async m => AsyncThread m a -> m a -- | This will discard the MonadEffect Async m -- constraint by forcing m to be IO. The functions -- doesn't actually do anything, the real implementation is given by the -- MonadEffect Async IO instance which uses the -- async package. implementAsyncViaIO :: IO a -> IO a instance GHC.Classes.Ord (Control.Effects.Async.AsyncThread m a) instance GHC.Classes.Eq (Control.Effects.Async.AsyncThread m a) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Effects.Async.AsyncThread m) instance Control.Effects.Effect Control.Effects.Async.Async instance Control.Effects.MonadEffect Control.Effects.Async.Async GHC.Types.IO -- | The Yield a effect lets a computation produce values -- of type a during it's execution. module Control.Effects.Yield data Yield a -- | Output a value of type a. The semantics are determined by the -- implementation, but usually this will block until the next value is -- requested by the consumer. yield :: forall a m. MonadEffect (Yield a) m => a -> m () -- | Implement Yield by using non-determinism to output each of the -- values. This means you can use the functions from -- Control.Effects.List to choose how to consume them. For -- example, using evaluateToList will give you a list of all -- yielded values. It also means the yield calls won't block since -- all the values are requested. Other consumer functions give you more -- control. implementYieldViaNonDeterminism :: forall a m b. MonadEffect NonDeterminism m => RuntimeImplemented (Yield a) (RuntimeImplemented (Signal a ()) (ExceptT a m)) b -> m a -- | Implement Yield through an MVar. The result is a monadic -- action (the inner one) that returns one yielded value or -- Nothing if the computation is finished. All subsequent calls -- will also return Nothing. Each execution of this action -- continues execution in the provided computation, which is otherwise -- suspended. -- -- If the provided computation forks new threads and doesn't wait for -- them to finish, Nothing may be returned prematurely (in the -- sense that maybe there's still a live thread yielding values). -- -- Since the yielding is done through a shared MVar, this -- implementation is suitable to be run with multiple threads. Scheduling -- which thread gets continued is defined by the semantics of -- MVars. -- -- implementYieldViaMVar :: forall a m b. (MonadIO m, MonadEffect Async m) => RuntimeImplemented (Yield a) m b -> m (m (Maybe a)) -- | Implements Yield through a Chan. The resulting monadic -- action (the inner one) reads one value from the queue. Nothing -- means the provided computation is done. If the provided computation -- forks new threads and doesn't wait for them to finish, Nothing -- may be written prematurely (in the sense that maybe there's still a -- live thread yielding values). -- -- implementYieldViaChan :: forall a m b. (MonadIO m, MonadEffect Async m) => RuntimeImplemented (Yield a) m b -> m (m (Maybe a)) -- | A convenience function to go through all the yielded results. Use in -- combination with one of the implementations. Collects a list of -- values. traverseYielded :: Monad m => m (Maybe a) -> (a -> m b) -> m [b] -- | A convenience function to go through all the yielded results. Use in -- combination with one of the implementations. Discards the computed -- values. traverseYielded_ :: Monad m => m (Maybe a) -> (a -> m b) -> m () instance GHC.Generics.Generic (Control.Effects.EffMethods (Control.Effects.Yield.Yield a) m) instance Control.Effects.Effect (Control.Effects.Yield.Yield a) -- | This part of the tutorial will explain the basics behind -- simple-effects and how to use the effects provided by the -- library. To learn how to implement your own effects, check out the -- other parts. -- -- You'll need to enable some extensions to follow along: -- TypeApplications, FlexibleContexts, -- OverloadedStrings, DataKinds. module Tutorial.T1_Introduction -- | In this part, we'll take a more detailed look at this library. You -- don't need to know these things to use the effects. For the most part, -- you can also implement your own without reading this part. To learn -- about that check out the next part: Tutorial.T3_CustomEffects. -- -- That being said, the details will help you understand potential -- compiler errors you might get. Also, implementing more complex effects -- does require a bit of an understanding of the internals. module Tutorial.T2_Details -- | Let's see how we can implement custom effects. We'll go through a -- couple of examples of increasing complexity. This part does not -- require going through part 2. That being said, understanding the -- details will help with understanding some of the restrictions and will -- help with compiler errors you might get. module Tutorial.T3_CustomEffects