HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Moduleeffectful-core-2.3.0.1Haskell2010

Effectful.Internal.Monad

The Eff monad.

This module is intended for internal use only, and may change without warning in subsequent releases.

  • 12 types
  • 1 class
  • 33 values

The Eff monad

2 declarations
newtypenewtype Eff (es :: [Effect]) a
#

The Eff monad provides the implementation of a computation that performs an arbitrary set of effects. In Eff es a, es is a type-level list that contains all the effects that the computation may perform. For example, a computation that produces an Integer by consuming a String from the global environment and acting upon a single mutable value of type Bool would have the following type:

(Reader String :> es, State Bool :> es) => Eff es Integer

Abstracting over the list of effects with (:>):

  • Allows the computation to be used in functions that may perform other effects.

  • Allows the effects to be handled in any order.

Instances19MonadBase, MonadBaseControl, Monad, Functor, MonadFix, MonadFail, …
  • IOE :> es => MonadBase IO (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad

    Instance included for compatibility with existing code.

    Usage of liftIO is preferrable as it's a standard.

  • IOE :> es => MonadBaseControl IO (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad

    Instance included for compatibility with existing code.

    Usage of withEffToIO is preferrable as it allows specifying the UnliftStrategy on a case-by-case basis and has better error reporting.

    Note: the unlifting strategy for liftBaseWith is taken from the IOE context (see unliftStrategy).

  • Monad (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • Functor (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • MonadFix (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • Fail :> es => MonadFail (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • Applicative (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • NonDet :> es => Alternative (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • NonDet :> es => MonadPlus (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • IOE :> es => MonadIO (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • MonadCatch (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • MonadMask (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • MonadThrow (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • Prim :> es => PrimMonad (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • IOE :> es => MonadUnliftIO (Eff es)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad

    Instance included for compatibility with existing code.

    Usage of withEffToIO is preferrable as it allows specifying the UnliftStrategy on a case-by-case basis and has better error reporting.

    Note: the unlifting strategy for withRunInIO is taken from the IOE context (see unliftStrategy).

  • Semigroup a => Semigroup (Eff es a)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • Monoid a => Monoid (Eff es a)Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • type PrimState (Eff es) = PrimStateEffDefined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • type StM (Eff es) a = aDefined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
valuerunPureEff :: Eff '[] a -> a
#

Run a pure Eff computation.

For running computations with side effects see runEff.

Access to the internal representation

valueunsafeEff :: (Env es -> IO a) -> Eff es a
#

Access the underlying IO monad along with the environment.

This function is unsafe because it can be used to introduce arbitrary IO actions into pure Eff computations.

valueunsafeEff_ :: IO a -> Eff es a
#

Access the underlying IO monad.

This function is unsafe because it can be used to introduce arbitrary IO actions into pure Eff computations.

NonDet

1 declaration

Fail

1 declaration

IO

2 declarations
datadata IOE (a :: Type -> Type) b
#

Run arbitrary IO computations via MonadIO or MonadUnliftIO.

Note: it is not recommended to use this effect in application code as it is too liberal. Ideally, this is only used in handlers of more fine-grained effects.

Instances2DispatchOf, StaticRep

Prim

3 declarations
datadata Prim (a :: Type -> Type) b
#

Provide the ability to perform primitive state-transformer actions.

Instances2DispatchOf, StaticRep

Lifting

5 declarations
valueraise :: Eff es a -> Eff (e ': es) a
#

Lift an Eff computation into an effect stack with one more effect.

valueraiseWith
  1. :: HasCallStack
  2. => UnliftStrategy
  3. -> ((forall r. Eff (e ': es) r -> Eff es r) -> Eff es a)

    Continuation with the unlifting function in scope.

  4. -> Eff (e ': es) a
#

Lift an Eff computation into an effect stack with one more effect and create an unlifting function with the given strategy.

valuesubsume :: e :> es => Eff (e ': es) a -> Eff es a
#

Eliminate a duplicate effect from the top of the effect stack.

valueinject :: Subset xs es => Eff xs a -> Eff es a
#

Allow for running an effect stack xs within es as long as xs is a permutation (with possible duplicates) of a subset of es.

Generalizes raise and subsume.

Example3 expressions
data E1 :: Effectdata E2 :: Effectdata E3 :: Effect

It makes it possible to rearrange the effect stack however you like:

Example1 expression
:{  shuffle :: Eff (E3 : E1 : E2 : es) a -> Eff (E1 : E2 : E3 : es) a  shuffle = inject:}

It can also turn a monomorphic effect stack into a polymorphic one:

Example1 expression
:{  toPoly :: (E1 :> es, E2 :> es, E3 :> es) => Eff [E1, E2, E3] a -> Eff es a  toPoly = inject:}

Moreover, it allows for hiding specific effects from downstream:

Example1 expression
:{  onlyE1 :: Eff (E1 : es) a -> Eff (E1 : E2 : E3 : es) a  onlyE1 = inject:}
Example1 expression
:{  onlyE2 :: Eff (E2 : es) a -> Eff (E1 : E2 : E3 : es) a  onlyE2 = inject:}
Example1 expression
:{  onlyE3 :: Eff (E3 : es) a -> Eff (E1 : E2 : E3 : es) a  onlyE3 = inject:}

However, it's not possible to inject a computation into an incompatible effect stack:

Example1 expression
:{  coerceEs :: Eff es1 a -> Eff es2 a  coerceEs = inject:}......Couldn't match type ‘es1’ with ‘es2’...

Unlifting

8 declarations
datadata UnliftStrategy
#

The strategy to use when unlifting Eff computations via withEffToIO or the localUnlift family.

Constructors

  • SeqUnlift

    The sequential strategy is the fastest and a default setting for IOE. Any attempt of calling the unlifting function in threads distinct from its creator will result in a runtime error.

  • ConcUnlift !Persistence !Limit

    The concurrent strategy makes it possible for the unlifting function to be called in threads distinct from its creator. See Persistence and Limit settings for more information.

Instances5Eq, Ord, Show, Generic, Rep
datadata Persistence
#

Persistence setting for the ConcUnlift strategy.

Different functions require different persistence strategies. Examples:

  • Lifting pooledMapConcurrentlyN from the unliftio library requires the Ephemeral strategy as we don't want jobs to share environment changes made by previous jobs run in the same worker thread.

  • Lifting forkIOWithUnmask requires the Persistent strategy, otherwise the unmasking function would start with a fresh environment each time it's called.

Constructors

  • Ephemeral

    Don't persist the environment between calls to the unlifting function in threads distinct from its creator.

  • Persistent

    Persist the environment between calls to the unlifting function within a particular thread.

Instances5Eq, Ord, Show, Generic, Rep
datadata Limit
#

Limit setting for the ConcUnlift strategy.

Constructors

  • Limited !Int

    Behavior dependent on the Persistence setting.

    For Ephemeral, it limits the amount of uses of the unlifting function in threads distinct from its creator to N. The unlifting function will create N copies of the environment when called N times and K+1 copies when called K < N times.

    For Persistent, it limits the amount of threads, distinct from the creator of the unlifting function, it can be called in to N. The amount of calls to the unlifting function within a particular threads is unlimited. The unlifting function will create N copies of the environment when called in N threads and K+1 copies when called in K < N threads.

  • Unlimited

    Unlimited use of the unlifting function.

Instances5Eq, Ord, Show, Generic, Rep
valuewithSeqEffToIO
  1. :: (HasCallStack, IOE :> es)
  2. => ((forall r. Eff es r -> IO r) -> IO a)

    Continuation with the unlifting function in scope.

  3. -> Eff es a
#

Create an unlifting function with the SeqUnlift strategy. For the general version see withEffToIO.

Note: usage of this function is preferrable to withRunInIO because of explicit unlifting strategy and better error reporting.

valuewithEffToIO
  1. :: (HasCallStack, IOE :> es)
  2. => UnliftStrategy
  3. -> ((forall r. Eff es r -> IO r) -> IO a)

    Continuation with the unlifting function in scope.

  4. -> Eff es a
#

Create an unlifting function with the given strategy.

Note: usage of this function is preferrable to withRunInIO because of explicit unlifting strategy and better error reporting.

Low-level unlifts

Dispatch

0 declarations

Dynamic dispatch

newtypenewtype LocalEnv (localEs :: [Effect]) (handlerEs :: [Effect])
#

Opaque representation of the Eff environment at the point of calling the send function, i.e. right before the control is passed to the effect handler.

The second type variable represents effects of a handler and is needed for technical reasons to guarantee soundness (see SharedSuffix for more information).

Constructors

datadata Handler (a :: Effect) where
#

An internal representation of dynamically dispatched effects, i.e. the effect handler bundled with its environment.

Constructors

Static dispatch

data familydata family StaticRep (e :: Effect)
#

Internal representations of statically dispatched effects.

Instances10StaticRep, …
  • data StaticRep IOEDefined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • data StaticRep Prim
    • Prim
    Defined in effectful-core-2.3.0.1 · Effectful.Internal.Monad
  • data StaticRep (Error e)
    • Error ErrorId
    Defined in effectful-core-2.3.0.1 · Effectful.Error.Static
  • data StaticRep (Labeled label e)Defined in effectful-core-2.3.0.1 · Effectful.Labeled
  • data StaticRep (Provider e input f)
    • Provider :: !Env handlerEs -> !(forall r. input -> Eff (e ': handlerEs) r -> Eff handlerEs (f r)) -> R:StaticRepProvider e input f
    Defined in effectful-core-2.3.0.1 · Effectful.Provider
  • data StaticRep (Reader r)
    • Reader r
    Defined in effectful-core-2.3.0.1 · Effectful.Reader.Static
  • data StaticRep (State s)
    • State s
    Defined in effectful-core-2.3.0.1 · Effectful.State.Static.Local
  • data StaticRep (State s)Defined in effectful-core-2.3.0.1 · Effectful.State.Static.Shared
  • data StaticRep (Writer w)
    • Writer w
    Defined in effectful-core-2.3.0.1 · Effectful.Writer.Static.Local
  • data StaticRep (Writer w)Defined in effectful-core-2.3.0.1 · Effectful.Writer.Static.Shared
valueevalStaticRep
  1. :: (DispatchOf e ~ 'Static sideEffects, MaybeIOE sideEffects es)
  2. => StaticRep e

    The initial representation.

  3. -> Eff (e ': es) a
  4. -> Eff es a
#

Run a statically dispatched effect with the given initial representation and return the final value, discarding the final representation.

Primitive operations