HORIZON HASKELLDocslts/ghc-10.0.x8fef28d2026-11-02Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8fef28d · 2026-11-02

Moduleeffectful-core-2.7.1.2GHC2021

Effectful.Provider

Turn an effect handler into an effectful operation.

Contents
  1. Example
  2. Effect
  3. Handlers
  4. Operations
Synopsis

Example

Example4 expressions
import Control.Monad.IO.Classimport Data.Map.Strict qualified as Mimport Effectful.Dispatch.Dynamicimport Effectful.State.Static.Local

Given an effect:

Example1 expression
:{  data Write :: Effect where    Write :: String -> Write m ()  type instance DispatchOf Write = Dynamic:}
Example1 expression
:{  write :: Write :> es => String -> Eff es ()  write = send . Write:}

its handler can be turned into an effectful operation with the Provider effect:

Example1 expression
:{  action :: Provider_ Write FilePath :> es => Eff es ()  action = do    provideWith_ @Write "in.txt" $ do      write "hi"      write "there"    provideWith_ @Write "out.txt" $ do      write "good"      write "bye":}

Then, given multiple interpreters:

Example1 expression
:{  runWriteIO    :: IOE :> es    => FilePath    -> Eff (Write : es) a    -> Eff es a  runWriteIO fp = interpret_ $ \case    Write msg -> liftIO . putStrLn $ fp ++ ": " ++ msg:}
Example1 expression
:{  runWritePure    :: State (M.Map FilePath [String]) :> es    => FilePath    -> Eff (Write : es) a    -> Eff es a  runWritePure fp = interpret_ $ \case    Write msg -> modify $ M.insertWith (++) fp [msg]:}

action can be supplied with either of them for the appropriate behavior:

Example1 expression
:{  runEff    . runProvider_ runWriteIO    $ action:}in.txt: hiin.txt: thereout.txt: goodout.txt: bye
Example1 expression
:{  runPureEff    . fmap (fmap reverse)    . execState @(M.Map FilePath [String]) M.empty    . runProvider_ runWritePure    $ action:}fromList [("in.txt",["hi","there"]),("out.txt",["good","bye"])]

Moreover, operations of the Provider effect can be intercepted with interpose, e.g. to adjust the input of the effect handler:

Example1 expression
:{  adjustPaths    :: Provider_ Write FilePath :> es    => Eff es a    -> Eff es a  adjustPaths = interpose @(Provider_ Write FilePath) $ \env -> \case    ProvideWith fp action -> do      passthrough env $ ProvideWith ("logs/" ++ fp) action:}
Example1 expression
:{  runEff    . runProvider_ runWriteIO    . adjustPaths    $ action:}logs/in.txt: hilogs/in.txt: therelogs/out.txt: goodlogs/out.txt: bye

Effect

datadata Provider (e :: Effect) input (f :: Type -> Type) (a :: Type -> Type) b where

Provide a way to run a handler of e with a given input.

Note: f can be used to alter the return type of the effect handler. If that's unnecessary, use Provider_.

Constructors

  • ProvideWith :: input -> Eff (e ': es) a -> Provider e input f a (f a)

    Run the effect handler with a given input.

Instances1DispatchOf

Handlers

Operations