-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Fast and concise extensible effects -- -- Please see the README on GitHub at -- https://github.com/re-xyr/cleff#readme @package cleff @version 0.1.0.0 -- | This module contains utility functions for Any. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Data.Any -- | The type constructor Any is type to which you can unsafely -- coerce any lifted type, and back. More concretely, for a lifted type -- t and value x :: t, -- unsafeCoerce -- (unsafeCoerce x :: Any) :: t is equivalent to x. type family Any :: k -- | Coerce Any to a boxed value. This is generally unsafe -- and it is your responsibility to ensure that the type you're coercing -- into is the original type that the Any is coerced from. fromAny :: Any -> a -- | Coerce any boxed value into Any. toAny :: a -> Any -- | This module defines an immutable extensible record type, similar to -- vinyl and data-diverse. However this implementation -- focuses on fast reads, hence has very different performance -- characteristics from other libraries: -- -- -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Data.Rec -- | Extensible record type supporting efficient <math> reads. The -- underlying implementation is SmallArray slices, therefore suits -- small numbers of entries (i.e. less than 128). data Rec (f :: k -> Type) (es :: [k]) -- | Get the length of the record. length :: Rec f es -> Int -- | Create an empty record. <math>. empty :: Rec f '[] -- | Create a record with one entry. <math>. singleton :: f e -> Rec f '[e] -- | Prepend one entry to the record. <math>. cons :: f e -> Rec f es -> Rec f (e : es) -- | Infix version of cons that also supports destructuring. pattern (:~:) :: f e -> Rec f es -> Rec f (e : es) infixr 5 :~: -- | Type level list concatenation. type family xs ++ ys infixr 5 ++ -- | Concatenate two records. <math>. concat :: Rec f es -> Rec f es' -> Rec f (es ++ es') -- | Infix version of concat that also supports destructuring. pattern (:++:) :: forall es es' f. KnownList es => Rec f es -> Rec f es' -> Rec f (es ++ es') infixr 5 :++: -- | Slice off one entry from the top of the record. <math>. tail :: Rec f (e : es) -> Rec f es -- | The list es list is concrete, i.e. is of the form '[a1, -- a2, ..., an], i.e. is not a type variable. class KnownList (es :: [k]) -- | Slice off several entries from the top of the record. <math>. drop :: forall es es' f. KnownList es => Rec f (es ++ es') -> Rec f es' -- | Get the head of the record. <math>. head :: Rec f (e : es) -> f e -- | Take elements from the top of the record. <math>. take :: forall es es' f. KnownList es => Rec f (es ++ es') -> Rec f es -- | The element e is present in the list es. class Elem (e :: k) (es :: [k]) -- | Get an element in the record. Amortized <math>. index :: forall e es f. Elem e es => Rec f es -> f e -- | es is a subset of es'. class KnownList es => Subset (es :: [k]) (es' :: [k]) -- | Get a subset of the record. Amortized <math>. pick :: forall es es' f. Subset es es' => Rec f es' -> Rec f es -- | Modify an entry in the record. <math>. modify :: forall e es f. Elem e es => f e -> Rec f es -> Rec f es -- | Infix version of modify. (/~/) :: Elem e es => f e -> Rec f es -> Rec f es infixl 9 /~/ -- | Merge a subset into the original record, updating several entries at -- once. <math>. batch :: forall es es' f. Subset es es' => Rec f es -> Rec f es' -> Rec f es' -- | Infix version of batch. (/++/) :: Subset es es' => Rec f es -> Rec f es' -> Rec f es' infixl 9 /++/ -- | The type of natural transformations from functor f to -- g. type f ~> g = forall a. f a -> g a infixr 0 ~> -- | Apply a natural transformation to the record. <math>. natural :: (f ~> g) -> Rec f es -> Rec g es -- | Infix version of natural. (<#>) :: (f ~> g) -> Rec f es -> Rec g es infixl 4 <#> -- | Zip two records with a natural transformation. <math>. zipWith :: (forall x. f x -> g x -> h x) -> Rec f es -> Rec g es -> Rec h es -- | Check if a predicate is true on all elements. <math>. all :: (forall x. f x -> Bool) -> Rec f es -> Bool -- | Check if a predicate is true on at least one element. <math>. any :: (forall x. f x -> Bool) -> Rec f es -> Bool -- | Convert a record that effectively contains a fixed type into a list of -- the fixed type. <math>. degenerate :: Rec (Const a) es -> [a] -- | Map each element to a fixed type. <math>. extract :: (forall x. f x -> a) -> Rec f es -> [a] -- | Test all invariants. invariant :: Rec f es -> Rec f es -- | Test the size invariant of Rec. sizeInvariant :: Rec f es -> Rec f es -- | Test whether all fields of Rec are really set. allAccessible :: Rec f es -> Rec f es instance forall k (es :: [k]). Data.Rec.Subset '[] es instance forall k (es :: [k]) (es' :: [k]) (e :: k). (Data.Rec.Subset es es', Data.Rec.Elem e es') => Data.Rec.Subset (e : es) es' instance forall k (e :: k). (TypeError ...) => Data.Rec.Elem e '[] instance forall a (e :: a) (es :: [a]). Data.Rec.Elem e (e : es) instance forall a (e :: a) (es :: [a]) (e' :: a). Data.Rec.Elem e es => Data.Rec.Elem e (e' : es) instance Data.Rec.KnownList '[] instance forall k (es :: [k]) (e :: k). Data.Rec.KnownList es => Data.Rec.KnownList (e : es) instance forall k (f :: k -> Type). GHC.Classes.Eq (Data.Rec.Rec f '[]) instance forall a (f :: a -> Type) (xs :: [a]) (x :: a). (GHC.Classes.Eq (Data.Rec.Rec f xs), GHC.Classes.Eq (f x)) => GHC.Classes.Eq (Data.Rec.Rec f (x : xs)) instance forall k (f :: k -> Type) (xs :: [k]). (forall (x :: k). GHC.Classes.Eq (f x)) => GHC.Classes.Eq (Data.Rec.Rec f xs) instance forall k (f :: k -> Type). GHC.Show.Show (Data.Rec.Rec f '[]) instance forall k (f :: k -> Type). GHC.Read.Read (Data.Rec.Rec f '[]) instance forall a (f :: a -> Type) (x :: a) (xs :: [a]). (GHC.Show.Show (f x), GHC.Show.Show (Data.Rec.Rec f xs)) => GHC.Show.Show (Data.Rec.Rec f (x : xs)) instance forall a (f :: a -> Type) (x :: a) (xs :: [a]). (GHC.Read.Read (f x), GHC.Read.Read (Data.Rec.Rec f xs)) => GHC.Read.Read (Data.Rec.Rec f (x : xs)) instance forall k (f :: k -> Type) (xs :: [k]). (forall (x :: k). GHC.Show.Show (f x)) => GHC.Show.Show (Data.Rec.Rec f xs) instance forall k (f :: k -> Type). GHC.Base.Semigroup (Data.Rec.Rec f '[]) instance forall a (f :: a -> Type) (x :: a) (xs :: [a]). (GHC.Base.Semigroup (f x), GHC.Base.Semigroup (Data.Rec.Rec f xs)) => GHC.Base.Semigroup (Data.Rec.Rec f (x : xs)) instance forall k (f :: k -> Type) (xs :: [k]). (forall (x :: k). GHC.Base.Semigroup (f x)) => GHC.Base.Semigroup (Data.Rec.Rec f xs) instance forall k (f :: k -> Type). GHC.Base.Monoid (Data.Rec.Rec f '[]) instance forall a (f :: a -> Type) (x :: a) (xs :: [a]). (GHC.Base.Monoid (f x), GHC.Base.Monoid (Data.Rec.Rec f xs)) => GHC.Base.Monoid (Data.Rec.Rec f (x : xs)) -- | Mem is a data structure that is a simulation of an array of -- thread-local pointers. This structure supports: -- -- -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Data.Mem -- | A simulated array of thread-local pointers. This means for each array -- cell, you can either change the pointer or change the memory the -- pointer points to. -- -- Note that like real memory, any of the operations provided is not -- generally safe and it is your responsibility to ensure the correctness -- of your calls. data Mem (f :: k -> Type) (es :: [k]) -- | The representation of a pointer in a Mem. data MemPtr (f :: k -> Type) (a :: k) -- | Create a Mem with no pointers. empty :: Mem f '[] -- | Adjust the array of pointers. adjust :: forall es' es f. (Rec (MemPtr f) es -> Rec (MemPtr f) es') -> Mem f es -> Mem f es' -- | Allocate a new address. <math>. alloca :: forall e es f. Mem f es -> (# MemPtr f e, Mem f es #) -- | Read a pointer. <math>. read :: forall e es f. Elem e es => Mem f es -> f e -- | Write to the memory a pointer points to. <math>. write :: forall e es f. MemPtr f e -> f e -> Mem f es -> Mem f es -- | Replace a pointer with a new one. <math>. replace :: forall e es f. Elem e es => MemPtr f e -> f e -> Mem f es -> Mem f es -- | Add a new pointer to the array. <math>. append :: forall e es f. MemPtr f e -> f e -> Mem f es -> Mem f (e : es) -- | Use the memory of LHS as a newer version for the memory of RHS. -- <math>. update :: forall es es' f. Mem f es' -> Mem f es -> Mem f es instance forall k (f :: k -> Type) (a :: k). GHC.Classes.Ord (Data.Mem.MemPtr f a) instance forall k (f :: k -> Type) (a :: k). GHC.Classes.Eq (Data.Mem.MemPtr f a) -- | This module contains definitions of some basic types related to -- effects. You won't need this module directly; these functionalities -- are reexported in the Cleff module. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Cleff.Internal.Effect -- | The type of effects. An effect e m a takes an effect monad -- type m :: Type -> Type and a result type -- a :: Type. type Effect = (Type -> Type) -> Type -> Type -- | e :> es means the effect e is present in -- the effect stack es, and therefore can be used in an -- Eff es computation. type (:>) = Elem infix 0 :> -- | xs :>> es means the list of effects xs -- are all present in the effect stack es. This is a convenient -- type alias for (e1 :> es, ..., en :> es). type family xs :>> es :: Constraint infix 0 :>> -- | Type level list concatenation. type family xs ++ ys infixr 5 ++ -- | The type of natural transformations from functor f to -- g. type f ~> g = forall a. f a -> g a infixr 0 ~> -- | This module contains the definition of the Eff monad, which is -- basically an Env es -> IO a, as well as -- functions for manipulating the effect environment type Env. -- Most of the times, you won't need to use this module directly; -- user-facing functionalities are all exported via the Cleff -- module. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Cleff.Internal.Monad -- | The internal representation of effect handlers. This is just a natural -- transformation from the effect type e (Eff es) to the -- effect monad Eff es for any effect stack es. -- -- In interpreting functions (see Cleff.Internal.Interpret), the -- user-facing Handler type is transformed into this type. newtype InternalHandler e InternalHandler :: (forall es. e (Eff es) ~> Eff es) -> InternalHandler e [runHandler] :: InternalHandler e -> forall es. e (Eff es) ~> Eff es -- | The effect memironment that stores handlers of any effect present in -- the stack es. type Env = Mem InternalHandler -- | The extensible effect monad. A monad Eff es is capable -- of performing any effect in the effect stack es, which -- is a type-level list that holds all effects available. However, most -- of the times, for flexibility, es should be a polymorphic -- type variable, and you should use the (:>) and -- (:>>) operators in constraints to indicate what effects -- are in the stack. For example, -- --
--   Reader String :> es, State Bool :> es => Eff es Integer
--   
-- -- allows you to perform operations of the Reader -- String effect and the State Bool -- effect in a computation returning an Integer. newtype Eff es a Eff :: (Env es -> IO a) -> Eff es a [unEff] :: Eff es a -> Env es -> IO a -- | The list es list is concrete, i.e. is of the form '[a1, -- a2, ..., an], i.e. is not a type variable. class KnownList (es :: [k]) -- | es is a subset of es'. class KnownList es => Subset (es :: [k]) (es' :: [k]) -- | Perform an effect operation, i.e. a value of an effect type -- e :: Effect. This requires e to be in the -- effect stack. send :: e :> es => e (Eff es) ~> Eff es instance Control.Monad.Fix.MonadFix (Cleff.Internal.Monad.Eff es) instance GHC.Base.Monad (Cleff.Internal.Monad.Eff es) instance GHC.Base.Applicative (Cleff.Internal.Monad.Eff es) instance GHC.Base.Functor (Cleff.Internal.Monad.Eff es) instance GHC.Base.Monoid a => GHC.Base.Monoid (Cleff.Internal.Monad.Eff es a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Cleff.Internal.Monad.Eff es a) instance Data.Typeable.Internal.Typeable e => GHC.Show.Show (Cleff.Internal.Monad.InternalHandler e) -- | This module contains Template Haskell functions for generating -- definitions of functions that send effect operations. You mostly won't -- want to import this module directly; The Cleff module reexports -- the main functionalities of this module. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Cleff.Internal.TH -- | For a datatype T representing an effect, -- makeEffect T generates functions defintions for -- performing the operations of T via send. The naming -- rule is changing the first uppercase letter in the constructor name to -- lowercase or removing the : symbol in the case of operator -- constructors. Also, this function will preserve any fixity -- declarations defined on the constructors. -- -- Because of the limitations of Template Haskell, all constructors of -- T should be polymorphic in the monad type, if they are -- to be used by makeEffect. For example, this is not OK: -- --
--   data Limited :: Effect where
--     Noop :: Limited (Eff es) ()
--   
-- -- because the monad type Eff es is not a fully -- polymorphic type variable. -- -- This function is also "weaker" than polysemy's -- makeSem, because this function cannot properly handle some -- cases involving complex higher order effects. Those cases are rare, -- though. See the tests for more details. makeEffect :: Name -> Q [Dec] -- | Like makeEffect, but doesn't generate type signatures. This is -- useful when you want to attach Haddock documentation to the function -- signature, e.g.: -- --
--   data Identity :: Effect where
--     Noop :: Identity m ()
--   makeEffect_ ''Identity
--   
--   -- | Perform nothing at all.
--   noop :: Identity :> es => Eff es ()
--   
-- -- Be careful that the function signatures must be added after the -- makeEffect_ call. makeEffect_ :: Name -> Q [Dec] -- | This module contains functions for interpreting effects. Most of the -- times you won't need to import this directly; the module Cleff -- reexports most of the functionalities. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Cleff.Internal.Interpret -- | Lift a computation into a bigger effect stack with one more effect. -- For a more general version see raiseN. raise :: forall e es. Eff es ~> Eff (e : es) -- | Lift a computation into a bigger effect stack with arbitrarily more -- effects. This function requires TypeApplications. raiseN :: forall es' es. KnownList es' => Eff es ~> Eff (es' ++ es) -- | Lift a computation with a fixed, known effect stack into some superset -- of the stack. inject :: forall es' es. Subset es' es => Eff es' ~> Eff es -- | Eliminate a duplicate effect from the top of the effect stack. For a -- more general version see subsumeN. subsume :: forall e es. e :> es => Eff (e : es) ~> Eff es -- | Eliminate several duplicate effects from the top of the effect stack. -- This function requires TypeApplications. subsumeN :: forall es' es. Subset es' es => Eff (es' ++ es) ~> Eff es -- | The typeclass that indicates a handler scope, handling effect -- e sent from the effect stack esSend in the effect -- stack es. -- -- You should not define instances for this typeclass whatsoever. class Handling e es esSend | e -> es esSend, es -> e esSend, esSend -> e es -- | Get the send-site Env. sendEnv :: Handling e es esSend => Env esSend -- | The type of an effect handler, which is a function that -- transforms an effect e from an arbitrary effect stack into -- computations in the effect stack es. type Handler e es = forall esSend. Handling e es esSend => e (Eff esSend) ~> Eff es -- | The type of a simple transformation function from effect e to -- e'. type Translator e e' = forall esSend. e (Eff esSend) ~> e' (Eff esSend) -- | Interpret an effect e in terms of effects in the effect stack -- es with an effect handler. interpret :: forall e es. Handler e es -> Eff (e : es) ~> Eff es -- | Like interpret, but adds a new effect e' that can be -- used in the handler. reinterpret :: forall e' e es. Handler e (e' : es) -> Eff (e : es) ~> Eff (e' : es) -- | Like reinterpret, but adds two new effects. reinterpret2 :: forall e' e'' e es. Handler e (e' : (e'' : es)) -> Eff (e : es) ~> Eff (e' : (e'' : es)) -- | Like reinterpret, but adds three new effects. reinterpret3 :: forall e' e'' e''' e es. Handler e (e' : (e'' : (e''' : es))) -> Eff (e : es) ~> Eff (e' : (e'' : (e''' : es))) -- | Like reinterpret, but adds arbitrarily many new effects. This -- function requires TypeApplications. reinterpretN :: forall es' e es. KnownList es' => Handler e (es' ++ es) -> Eff (e : es) ~> Eff (es' ++ es) -- | Respond to an effect while being able to leave it unhandled (i.e. you -- can resend the effects in the handler). interpose :: forall e es. e :> es => Handler e es -> Eff es ~> Eff es -- | Like interpose, but allows to introduce one new effect to use -- in the handler. impose :: forall e' e es. e :> es => Handler e (e' : es) -> Eff es ~> Eff (e' : es) -- | Like impose, but allows introducing arbitrarily many effects. -- This requires TypeApplications. imposeN :: forall es' e es. (KnownList es', e :> es) => Handler e (es' ++ es) -> Eff es ~> Eff (es' ++ es) -- | Interpret an effect in terms of another effect in the stack via a -- simple Translator. transform :: forall e' e es. e' :> es => Translator e e' -> Eff (e : es) ~> Eff es -- | Like transform, but instead of using an effect in stack, add a -- new one to the top of it. translate :: forall e' e es. Translator e e' -> Eff (e : es) ~> Eff (e' : es) -- | Run a computation in the current effect stack. This is useful for -- interpreting higher-order effects, like a bracketing effect: -- --
--   data Resource m a where
--     Bracket :: m a -> (a -> m ()) -> (a -> m b) -> Resource m b
--   
-- --
--   Bracket alloc dealloc use ->
--     bracket
--       (toEff alloc)
--       (toEff . dealloc)
--       (toEff . use)
--   
toEff :: Handling e es esSend => Eff esSend ~> Eff es -- | Run a computation in the current effect stack, but handles the current -- effect inside the computation differently by providing a new -- Handler. This is useful for interpreting effects with local -- contexts, like Local: -- --
--   runReader :: r -> Eff (Reader r ': es) ~> Eff es
--   runReader x = interpret (handle x)
--     where
--       handle :: r -> Handler (Reader r) es
--       handle r = \case
--         Ask       -> pure r
--         Local f m -> toEffWith (handle $ f r) m
--   
toEffWith :: Handling e es esSend => Handler e es -> Eff esSend ~> Eff es -- | Temporarily gain the ability to lift some Eff es -- actions into Eff esSend. This is useful for dealing -- with effect operations with the monad type in the negative position, -- which means it's unlikely that you need to use this function in -- implementing your effects. withFromEff :: Handling e es esSend => ((Eff es ~> Eff esSend) -> Eff esSend a) -> Eff es a -- | This module contains the IOE effect together with a few -- primitives for using it, as well as interpretation combinators for -- IO-related effects. It is not usually needed because safe -- functionalities are re-exported in the Cleff module. -- -- This is an internal module and its API may change even -- between minor versions. Therefore you should be extra careful if -- you're to depend on this module. module Cleff.Internal.Base -- | The effect for lifting and unlifting the IO monad, allowing you -- to use MonadIO, MonadUnliftIO, PrimMonad, -- MonadCatch, MonadThrow and MonadMask -- functionalities. This is the "final" effect that most effects -- eventually are interpreted into. For example, you can do: -- --
--   log :: IOE :> es => Eff es ()
--   log = liftIO (putStrLn "Test logging")
--   
-- -- It is not recommended to use this effect in application code, as it is -- too liberal and allows arbitrary IO. Ideally, this is only used in -- interpreting more fine-grained effects. -- -- Note that this is not a real effect and cannot be interpreted -- in any way besides thisIsPureTrustMe and runIOE. It is -- similar to Polysemy's Final effect which also cannot be -- interpreted. This is mainly for performance concern, but also that -- there doesn't really exist reasonable interpretations other than the -- current one, given the underlying implementation of the Eff -- monad. -- -- IOE can be a real effect though, and you can enable the -- dynamic-ioe build flag to have that. However it is only for -- reference purposes and should not be used in production code. data IOE :: Effect -- | Lift an IO computation into Eff. This function is -- highly unsafe and should not be used directly; use -- liftIO instead, or if you're interpreting higher-order effects, -- use fromIO. primLiftIO :: IO a -> Eff es a -- | Give a runner function a way to run Eff actions as an IO -- computation. This function is highly unsafe and should not be -- used directly; use withRunInIO instead, or if you're -- interpreting higher-order effects, use withToIO. primUnliftIO :: ((Eff es ~> IO) -> IO a) -> Eff es a -- | Unsafely eliminate an IOE effect from the top of the effect -- stack. This is mainly for implementing effects that uses IO but -- does not do anything really impure (i.e. can be safely used -- unsafeDupablePerformIO on), such as a State effect. thisIsPureTrustMe :: Eff (IOE : es) ~> Eff es -- | Unwrap an Eff computation with side effects into an IO -- computation, given that all effects other than IOE are -- interpreted. runIOE :: Eff '[IOE] ~> IO -- | Unwrap a pure Eff computation into a pure value, given that all -- effects are interpreted. runPure :: Eff '[] a -> a -- | The type of an IO effect handler, which is a function -- that transforms an effect e into IO computations. This -- is used for interpretIO. type HandlerIO e es = forall esSend. (Handling e es esSend) => e (Eff esSend) ~> IO -- | Interpret an effect in terms of IO, by transforming an effect -- into IO computations. -- --
--   interpretIO f = interpret (liftIO . f)
--   
interpretIO :: IOE :> es => HandlerIO e es -> Eff (e : es) ~> Eff es -- | Temporarily gain the ability to unlift an Eff esSend -- computation into IO. This is useful for dealing with -- higher-order effects that involves IO. withToIO :: (Handling e es esSend, IOE :> es) => ((Eff esSend ~> IO) -> IO a) -> Eff es a -- | Lift an IO computation into Eff esSend. This is -- useful for dealing with effect operations with the monad type in the -- negative position within IOE, like masking. fromIO :: (Handling e es esSend, IOE :> es) => IO ~> Eff esSend instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.IO.Class.MonadIO (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.IO.Unlift.MonadUnliftIO (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Catch.MonadThrow (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Catch.MonadCatch (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Catch.MonadMask (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Base.MonadBase GHC.Types.IO (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO (Cleff.Internal.Monad.Eff es) instance (Cleff.Internal.Base.IOE Cleff.Internal.Effect.:> es) => Control.Monad.Primitive.PrimMonad (Cleff.Internal.Monad.Eff es) -- | This library implements an extensible effects system, where -- sets of monadic actions ("effects") are encoded as datatypes, tracked -- at the type level and can have multiple different implementations. -- This means you can swap out implementations of certain monadic actions -- in mock tests or in different environments. The notion of "effect" is -- general here: it can be an IO-performing side effect, or just -- obtaining the value of a static global environment. -- -- In particular, this library consists of -- -- -- -- So, this library allows you to do two things: -- -- module Cleff -- | The extensible effect monad. A monad Eff es is capable -- of performing any effect in the effect stack es, which -- is a type-level list that holds all effects available. However, most -- of the times, for flexibility, es should be a polymorphic -- type variable, and you should use the (:>) and -- (:>>) operators in constraints to indicate what effects -- are in the stack. For example, -- --
--   Reader String :> es, State Bool :> es => Eff es Integer
--   
-- -- allows you to perform operations of the Reader -- String effect and the State Bool -- effect in a computation returning an Integer. data Eff es a -- | e :> es means the effect e is present in -- the effect stack es, and therefore can be used in an -- Eff es computation. type (:>) = Elem infix 0 :> -- | xs :>> es means the list of effects xs -- are all present in the effect stack es. This is a convenient -- type alias for (e1 :> es, ..., en :> es). type family xs :>> es :: Constraint infix 0 :>> -- | The type of effects. An effect e m a takes an effect monad -- type m :: Type -> Type and a result type -- a :: Type. type Effect = (Type -> Type) -> Type -> Type -- | The effect for lifting and unlifting the IO monad, allowing you -- to use MonadIO, MonadUnliftIO, PrimMonad, -- MonadCatch, MonadThrow and MonadMask -- functionalities. This is the "final" effect that most effects -- eventually are interpreted into. For example, you can do: -- --
--   log :: IOE :> es => Eff es ()
--   log = liftIO (putStrLn "Test logging")
--   
-- -- It is not recommended to use this effect in application code, as it is -- too liberal and allows arbitrary IO. Ideally, this is only used in -- interpreting more fine-grained effects. -- -- Note that this is not a real effect and cannot be interpreted -- in any way besides thisIsPureTrustMe and runIOE. It is -- similar to Polysemy's Final effect which also cannot be -- interpreted. This is mainly for performance concern, but also that -- there doesn't really exist reasonable interpretations other than the -- current one, given the underlying implementation of the Eff -- monad. -- -- IOE can be a real effect though, and you can enable the -- dynamic-ioe build flag to have that. However it is only for -- reference purposes and should not be used in production code. data IOE :: Effect -- | Unwrap a pure Eff computation into a pure value, given that all -- effects are interpreted. runPure :: Eff '[] a -> a -- | Unwrap an Eff computation with side effects into an IO -- computation, given that all effects other than IOE are -- interpreted. runIOE :: Eff '[IOE] ~> IO -- | Perform an effect operation, i.e. a value of an effect type -- e :: Effect. This requires e to be in the -- effect stack. send :: e :> es => e (Eff es) ~> Eff es -- | For a datatype T representing an effect, -- makeEffect T generates functions defintions for -- performing the operations of T via send. The naming -- rule is changing the first uppercase letter in the constructor name to -- lowercase or removing the : symbol in the case of operator -- constructors. Also, this function will preserve any fixity -- declarations defined on the constructors. -- -- Because of the limitations of Template Haskell, all constructors of -- T should be polymorphic in the monad type, if they are -- to be used by makeEffect. For example, this is not OK: -- --
--   data Limited :: Effect where
--     Noop :: Limited (Eff es) ()
--   
-- -- because the monad type Eff es is not a fully -- polymorphic type variable. -- -- This function is also "weaker" than polysemy's -- makeSem, because this function cannot properly handle some -- cases involving complex higher order effects. Those cases are rare, -- though. See the tests for more details. makeEffect :: Name -> Q [Dec] -- | Like makeEffect, but doesn't generate type signatures. This is -- useful when you want to attach Haddock documentation to the function -- signature, e.g.: -- --
--   data Identity :: Effect where
--     Noop :: Identity m ()
--   makeEffect_ ''Identity
--   
--   -- | Perform nothing at all.
--   noop :: Identity :> es => Eff es ()
--   
-- -- Be careful that the function signatures must be added after the -- makeEffect_ call. makeEffect_ :: Name -> Q [Dec] -- | Lift a computation into a bigger effect stack with one more effect. -- For a more general version see raiseN. raise :: forall e es. Eff es ~> Eff (e : es) -- | Lift a computation into a bigger effect stack with arbitrarily more -- effects. This function requires TypeApplications. raiseN :: forall es' es. KnownList es' => Eff es ~> Eff (es' ++ es) -- | Lift a computation with a fixed, known effect stack into some superset -- of the stack. inject :: forall es' es. Subset es' es => Eff es' ~> Eff es -- | Eliminate a duplicate effect from the top of the effect stack. For a -- more general version see subsumeN. subsume :: forall e es. e :> es => Eff (e : es) ~> Eff es -- | Eliminate several duplicate effects from the top of the effect stack. -- This function requires TypeApplications. subsumeN :: forall es' es. Subset es' es => Eff (es' ++ es) ~> Eff es -- | The list es list is concrete, i.e. is of the form '[a1, -- a2, ..., an], i.e. is not a type variable. class KnownList (es :: [k]) -- | es is a subset of es'. class KnownList es => Subset (es :: [k]) (es' :: [k]) -- | The type of an effect handler, which is a function that -- transforms an effect e from an arbitrary effect stack into -- computations in the effect stack es. type Handler e es = forall esSend. Handling e es esSend => e (Eff esSend) ~> Eff es -- | Interpret an effect e in terms of effects in the effect stack -- es with an effect handler. interpret :: forall e es. Handler e es -> Eff (e : es) ~> Eff es -- | Like interpret, but adds a new effect e' that can be -- used in the handler. reinterpret :: forall e' e es. Handler e (e' : es) -> Eff (e : es) ~> Eff (e' : es) -- | Like reinterpret, but adds two new effects. reinterpret2 :: forall e' e'' e es. Handler e (e' : (e'' : es)) -> Eff (e : es) ~> Eff (e' : (e'' : es)) -- | Like reinterpret, but adds three new effects. reinterpret3 :: forall e' e'' e''' e es. Handler e (e' : (e'' : (e''' : es))) -> Eff (e : es) ~> Eff (e' : (e'' : (e''' : es))) -- | Like reinterpret, but adds arbitrarily many new effects. This -- function requires TypeApplications. reinterpretN :: forall es' e es. KnownList es' => Handler e (es' ++ es) -> Eff (e : es) ~> Eff (es' ++ es) -- | Respond to an effect while being able to leave it unhandled (i.e. you -- can resend the effects in the handler). interpose :: forall e es. e :> es => Handler e es -> Eff es ~> Eff es -- | Like interpose, but allows to introduce one new effect to use -- in the handler. impose :: forall e' e es. e :> es => Handler e (e' : es) -> Eff es ~> Eff (e' : es) -- | Like impose, but allows introducing arbitrarily many effects. -- This requires TypeApplications. imposeN :: forall es' e es. (KnownList es', e :> es) => Handler e (es' ++ es) -> Eff es ~> Eff (es' ++ es) -- | The type of an IO effect handler, which is a function -- that transforms an effect e into IO computations. This -- is used for interpretIO. type HandlerIO e es = forall esSend. (Handling e es esSend) => e (Eff esSend) ~> IO -- | Interpret an effect in terms of IO, by transforming an effect -- into IO computations. -- --
--   interpretIO f = interpret (liftIO . f)
--   
interpretIO :: IOE :> es => HandlerIO e es -> Eff (e : es) ~> Eff es -- | The type of a simple transformation function from effect e to -- e'. type Translator e e' = forall esSend. e (Eff esSend) ~> e' (Eff esSend) -- | Interpret an effect in terms of another effect in the stack via a -- simple Translator. transform :: forall e' e es. e' :> es => Translator e e' -> Eff (e : es) ~> Eff es -- | Like transform, but instead of using an effect in stack, add a -- new one to the top of it. translate :: forall e' e es. Translator e e' -> Eff (e : es) ~> Eff (e' : es) -- | The typeclass that indicates a handler scope, handling effect -- e sent from the effect stack esSend in the effect -- stack es. -- -- You should not define instances for this typeclass whatsoever. class Handling e es esSend | e -> es esSend, es -> e esSend, esSend -> e es -- | Run a computation in the current effect stack. This is useful for -- interpreting higher-order effects, like a bracketing effect: -- --
--   data Resource m a where
--     Bracket :: m a -> (a -> m ()) -> (a -> m b) -> Resource m b
--   
-- --
--   Bracket alloc dealloc use ->
--     bracket
--       (toEff alloc)
--       (toEff . dealloc)
--       (toEff . use)
--   
toEff :: Handling e es esSend => Eff esSend ~> Eff es -- | Run a computation in the current effect stack, but handles the current -- effect inside the computation differently by providing a new -- Handler. This is useful for interpreting effects with local -- contexts, like Local: -- --
--   runReader :: r -> Eff (Reader r ': es) ~> Eff es
--   runReader x = interpret (handle x)
--     where
--       handle :: r -> Handler (Reader r) es
--       handle r = \case
--         Ask       -> pure r
--         Local f m -> toEffWith (handle $ f r) m
--   
toEffWith :: Handling e es esSend => Handler e es -> Eff esSend ~> Eff es -- | Temporarily gain the ability to lift some Eff es -- actions into Eff esSend. This is useful for dealing -- with effect operations with the monad type in the negative position, -- which means it's unlikely that you need to use this function in -- implementing your effects. withFromEff :: Handling e es esSend => ((Eff es ~> Eff esSend) -> Eff esSend a) -> Eff es a -- | Temporarily gain the ability to unlift an Eff esSend -- computation into IO. This is useful for dealing with -- higher-order effects that involves IO. withToIO :: (Handling e es esSend, IOE :> es) => ((Eff esSend ~> IO) -> IO a) -> Eff es a -- | Lift an IO computation into Eff esSend. This is -- useful for dealing with effect operations with the monad type in the -- negative position within IOE, like masking. fromIO :: (Handling e es esSend, IOE :> es) => IO ~> Eff esSend -- | The type of natural transformations from functor f to -- g. type f ~> g = forall a. f a -> g a infixr 0 ~> -- | Type level list concatenation. type family xs ++ ys infixr 5 ++ -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | Monads which allow their actions to be run in IO. -- -- While MonadIO allows an IO action to be lifted into -- another monad, this class captures the opposite concept: allowing you -- to capture the monadic context. Note that, in order to meet the laws -- given below, the intuition is that a monad must have no monadic state, -- but may have monadic context. This essentially limits -- MonadUnliftIO to ReaderT and IdentityT -- transformers on top of IO. -- -- Laws. For any value u returned by askUnliftIO, it must -- meet the monad transformer laws as reformulated for -- MonadUnliftIO: -- -- -- -- Instances of MonadUnliftIO must also satisfy the idempotency -- law: -- -- -- -- This law showcases two properties. First, askUnliftIO doesn't -- change the monadic context, and second, liftIO . unliftIO u -- is equivalent to id IF called in the same monadic context as -- askUnliftIO. class MonadIO m => MonadUnliftIO (m :: Type -> Type) -- | Convenience function for capturing the monadic context and running an -- IO action with a runner function. The runner function is used -- to run a monadic action m in IO. withRunInIO :: MonadUnliftIO m => ((forall a. () => m a -> IO a) -> IO b) -> m b module Cleff.Writer -- | An effect capable of accumulating outputs. This roughly corresponds to -- the MonadWriter typeclass and WriterT monad -- transformer in the mtl approach. -- -- However, note that this does not have a pass operation as we -- are not sure what its semantics should be. In fact, the pass -- semantics in mtl is also unclear and will change when -- handlers are put in different orders. To avoid any confusion we -- decided it is best that we don't include it because no one seems to be -- relying on it anyway. data Writer w :: Effect [Tell] :: w -> Writer w m () [Listen] :: m a -> Writer w m (a, w) tell :: Writer w_ajRn :> es_ajWf => w_ajRn -> Eff es_ajWf () listen :: Writer w_ajRr :> es_ajWd => Eff es_ajWd a_XjRr -> Eff es_ajWd (a_XjRr, w_ajRr) -- | Apply a function to the accumulated output of listen. listens :: Writer w :> es => (w -> x) -> Eff es a -> Eff es (a, x) -- | Run a monoidal Writer effect. -- -- Caveat: Both runWriter and listens under -- runWriter will stop taking care of writer operations done on -- forked threads as soon as the main thread finishes its computation. -- Any writer operation done before main thread finishes is still -- taken into account. runWriter :: forall w es a. Monoid w => Eff (Writer w : es) a -> Eff es (a, w) module Cleff.State -- | An effect capable of providing a mutable state s that can be -- read and written. This roughly corresponds to the MonadState -- typeclass and StateT monad transformer in the mtl -- approach. data State s :: Effect [Get] :: State s m s [Put] :: s -> State s m () [State] :: (s -> (a, s)) -> State s m a get :: State s_akp0 :> es_akrc => Eff es_akrc s_akp0 put :: State s_akp2 :> es_akra => s_akp2 -> Eff es_akra () state :: State s_akp4 :> es_akr8 => (s_akp4 -> (a_akp5, s_akp4)) -> Eff es_akr8 a_akp5 -- | Apply a function to the result of get. gets :: State s :> es => (s -> t) -> Eff es t -- | Modify the value of the state via a function. modify :: State s :> es => (s -> s) -> Eff es () -- | Run the State effect. -- -- Caveat: The runState interpreter is implemented with -- IORefs and there is no way to do arbitrary atomic transactions. -- The state operation is atomic though and it is implemented with -- atomicModifyIORefCAS, which can be faster than -- atomicModifyIORef in contention. For any more complicated -- cases of atomicity, please build your own effect that uses either -- MVars or TVars based on your need. -- -- Unlike mtl, in cleff the state will not -- revert when an error is thrown. -- -- runState will stop taking care of state operations done on -- forked threads as soon as the main thread finishes its computation. -- Any state operation done before main thread finishes is still -- taken into account. runState :: s -> Eff (State s : es) a -> Eff es (a, s) -- | Run a State effect in terms of a larger State via a -- Lens'. zoom :: State t :> es => Lens' t s -> Eff (State s : es) ~> Eff es module Cleff.Reader -- | An effect capable of providing an immutable environment r -- that can be read. This roughly corresponds to the MonadReader -- typeclass and ReaderT monad transformer in the mtl -- approach. data Reader r :: Effect [Ask] :: Reader r m r [Local] :: (r -> r) -> m a -> Reader r m a ask :: Reader r_al10 :> es_al2D => Eff es_al2D r_al10 local :: Reader r_al12 :> es_al2A => (r_al12 -> r_al12) -> Eff es_al2A a_al14 -> Eff es_al2A a_al14 -- | Apply a function on the result of ask. asks :: Reader r :> es => (r -> s) -> Eff es s -- | Run a Reader effect with a given environment value. runReader :: r -> Eff (Reader r : es) ~> Eff es -- | Run a Reader effect in terms of a larger Reader via a -- Lens'. magnify :: Reader t :> es => Lens' t r -> Eff (Reader r : es) ~> Eff es module Cleff.Output -- | An effect that is capable of sending outputs, for example to a log -- file or an output stream. data Output o :: Effect [Output] :: o -> Output o m () output :: Output o_allx :> es_almj => o_allx -> Eff es_almj () -- | Run an Output effect by accumulating a list. outputToListState :: Eff (Output o : es) ~> Eff (State [o] : es) -- | Run an Output effect by translating it into a Writer. outputToWriter :: (o -> o') -> Eff (Output o : es) ~> Eff (Writer o' : es) -- | Ignore outputs of an Output effect altogether. ignoreOutput :: Eff (Output o : es) ~> Eff es -- | Run an Output effect by performing a computation for each -- output. runOutputEff :: (o -> Eff es ()) -> Eff (Output o : es) ~> Eff es module Cleff.Trace -- | An effect capable of logging messages, mostly for debugging purposes. data Trace :: Effect [Trace] :: String -> Trace m () trace :: Trace :> es_alCt => String -> Eff es_alCt () -- | Run the Trace effect by writing to a Handle. runTraceHandle :: IOE :> es => Handle -> Eff (Trace : es) a -> Eff es a -- | Run the Trace effect by writing to stdout. runTraceStdout :: IOE :> es => Eff (Trace : es) ~> Eff es -- | Run the Trace effect by writing to stderr. runTraceStderr :: IOE :> es => Eff (Trace : es) ~> Eff es -- | Run the Trace effect by ignoring all outputs altogether. ignoreTrace :: Eff (Trace : es) ~> Eff es -- | Transform the Trace effect into an Output -- String effect. traceToOutput :: Eff (Trace : es) ~> Eff (Output String : es) module Cleff.Mask -- | An effect capable of masking and specifically, -- bracketing operations, i.e. allowing cleanup after -- operations that my raise exceptions. data Mask :: Effect [Mask] :: ((m ~> m) -> m a) -> Mask m a [UninterruptibleMask] :: ((m ~> m) -> m a) -> Mask m a [Bracket] :: m a -> (a -> m c) -> (a -> m b) -> Mask m b [BracketOnError] :: m a -> (a -> m c) -> (a -> m b) -> Mask m b mask :: Mask :> es_alWM => ((~>) (Eff es_alWM) (Eff es_alWM) -> Eff es_alWM a_alTC) -> Eff es_alWM a_alTC uninterruptibleMask :: Mask :> es_alWK => ((~>) (Eff es_alWK) (Eff es_alWK) -> Eff es_alWK a_alTE) -> Eff es_alWK a_alTE bracket :: Mask :> es_alWG => Eff es_alWG a_XlTH -> (a_XlTH -> Eff es_alWG c_XlTJ) -> (a_XlTH -> Eff es_alWG b_alTI) -> Eff es_alWG b_alTI bracketOnError :: Mask :> es_alWC => Eff es_alWC a_XlTL -> (a_XlTL -> Eff es_alWC c_XlTN) -> (a_XlTL -> Eff es_alWC b_alTM) -> Eff es_alWC b_alTM -- | Variant of mask that does not provide a restoring function. mask_ :: Mask :> es => Eff es a -> Eff es a -- | Variant of uninterruptibleMask that does not provide a -- restoring function. uninterruptibleMask_ :: Mask :> es => Eff es a -> Eff es a -- | Variant of bracket that does not pass the allocated resource to -- the cleanup action. bracket_ :: Mask :> es => Eff es a -> Eff es c -> (a -> Eff es b) -> Eff es b -- | Attach a cleanup action that will always run to a potentially throwing -- computation. finally :: Mask :> es => Eff es a -> Eff es b -> Eff es a -- | Attach an action that runs if the main computation throws an -- exception. onError :: Mask :> es => Eff es a -> Eff es b -> Eff es a -- | Interpret the Mask effect in terms of primitive IO -- actions. runMask :: Eff (Mask : es) ~> Eff es module Cleff.Input -- | An effect that is capable of reading from some input source, such as -- an input stream. data Input i :: Effect [Input] :: Input i m i input :: Input i_amwe :> es_amwX => Eff es_amwX i_amwe -- | Apply a function to the result of input. inputs :: Input i :> es => (i -> i') -> Eff es i' -- | Run an Input effect by giving a constant input value. runInputConst :: i -> Eff (Input i : es) ~> Eff es -- | Run an Input effect by going through a list of values. inputToListState :: Eff (Input (Maybe i) : es) ~> Eff (State [i] : es) -- | Run an Input effect by performing a computation for each input -- request. runInputEff :: Eff es i -> Eff (Input i : es) ~> Eff es module Cleff.Fresh -- | An effect capable of generating unique values. This effect can be -- useful in generating variable indices. data Fresh u :: Effect [Fresh] :: Fresh u m u fresh :: Fresh u_amKA :> es_amLj => Eff es_amLj u_amKA -- | Interpret a Fresh Int effect in terms of -- State Int. freshIntToState :: Eff (Fresh Int : es) ~> Eff (State Int : es) -- | Interpret a Fresh Unique effect in terms of IO -- actions. runFreshUnique :: IOE :> es => Eff (Fresh Unique : es) ~> Eff es module Cleff.Error -- | An effect capable of breaking out of current control flow by raising -- an exceptional value e. This effect roughly corresponds to -- the MonadError typeclass and ExceptT monad -- transformer in mtl. data Error e :: Effect [ThrowError] :: e -> Error e m a [CatchError] :: m a -> (e -> m a) -> Error e m a throwError :: Error e_amUL :> es_amWz => e_amUL -> Eff es_amWz a_amUN catchError :: Error e_amUQ :> es_amWw => Eff es_amWw a_amUP -> (e_amUQ -> Eff es_amWw a_amUP) -> Eff es_amWw a_amUP -- | Lift an Either value into the Error effect. fromEither :: Error e :> es => Either e a -> Eff es a -- | Lift exceptions generated by an IO computation into the -- Error effect. fromException :: forall e es a. (Exception e, '[Error e, IOE] :>> es) => IO a -> Eff es a -- | Like fromException, but allows to transform the exception into -- another error type. fromExceptionVia :: (Exception ex, '[Error er, IOE] :>> es) => (ex -> er) -> IO a -> Eff es a -- | Lift exceptions generated by an Eff computation into the -- Error effect. fromExceptionEff :: forall e es a. (Exception e, '[Error e, IOE] :>> es) => Eff es a -> Eff es a -- | Like fromExceptionEff, but allows to transform the exception -- into another error type. fromExceptionEffVia :: (Exception ex, '[Error er, IOE] :>> es) => (ex -> er) -> Eff es a -> Eff es a -- | Try to extract a value from Maybe, throw an error otherwise. note :: Error e :> es => e -> Maybe a -> Eff es a -- | A variant of catchError that allows a predicate to choose -- whether to catch (Just) or rethrow (Nothing) the error. catchErrorJust :: Error e :> es => (e -> Maybe b) -> Eff es a -> (b -> Eff es a) -> Eff es a -- | A variant of catchError that allows a predicate to choose -- whether to catch (True) or rethrow (False) the error. catchErrorIf :: Error e :> es => (e -> Bool) -> Eff es a -> (e -> Eff es a) -> Eff es a -- | Flipped version of catchError. handleError :: Error e :> es => (e -> Eff es a) -> Eff es a -> Eff es a -- | Flipped version of catchErrorJust. handleErrorJust :: Error e :> es => (e -> Maybe b) -> (b -> Eff es a) -> Eff es a -> Eff es a -- | Flipped version of catchErrorIf. handleErrorIf :: Error e :> es => (e -> Bool) -> (e -> Eff es a) -> Eff es a -> Eff es a -- | Runs a computation, returning a Left value if an error was -- thrown. tryError :: Error e :> es => Eff es a -> Eff es (Either e a) -- | A variant of tryError that allows a predicate to choose whether -- to catch (True) or rethrow (False) the error. tryErrorJust :: Error e :> es => (e -> Maybe b) -> Eff es a -> Eff es (Either b a) -- | Run an Error effect. -- -- Caveat: runError is implemented with Exceptions -- therefore inherits some of its unexpected behavoirs. Errors thrown in -- forked threads will not be directly caught by -- catchErrors in the parent thread. Instead it will incur an -- exception, and we won't be quite able to display the details of that -- exception properly at that point. Therefore please properly handle the -- errors in the forked threads separately. -- -- However if you use async and wait for the action in -- the same effect scope (i.e. they get to be interpreted by the same -- runError handler), the error will be caught in the -- parent thread even if you don't deal with it in the forked thread. But -- if you passed the Async value out of the effect scope and -- waited for it elsewhere, the error will again not be caught. -- The best choice is not to pass Async values around -- randomly. runError :: forall e es a. Eff (Error e : es) a -> Eff es (Either e a) -- | Transform an Error into another. This is useful for aggregating -- multiple errors into one type. mapError :: forall e e' es. Error e' :> es => (e -> e') -> Eff (Error e : es) ~> Eff es instance GHC.Exception.Type.Exception Cleff.Error.ErrorExc instance GHC.Show.Show Cleff.Error.ErrorExc module Cleff.Fail -- | An effect that expresses failure with a message. This effect allows -- the use of the MonadFail class. data Fail :: Effect [Fail] :: String -> Fail m a -- | Run a Fail effect in terms of Error. runFail :: Eff (Fail : es) a -> Eff es (Either String a) -- | Run a Fail effect in terms of throwing exceptions in IO. runFailIO :: IOE :> es => Eff (Fail : es) ~> Eff es instance (Cleff.Fail.Fail Cleff.Internal.Effect.:> es) => Control.Monad.Fail.MonadFail (Cleff.Internal.Monad.Eff es)