polysemy-1.9.0.0: src/Polysemy.hs
-- | Description: Polysemy is a library for writing high-power, low-boilerplate domain specific languages
module Polysemy
( -- * Core Types
Sem ()
, Member
, Members
-- * Running Sem
, run
, runM
, runFinal
-- * Type synonyms for user convenience
, InterpreterFor
, InterpretersFor
-- * Interoperating With Other Monads
-- ** Embed
, Embed (..)
, embed
, embedToFinal
-- ** Final
-- | For advanced uses of 'Final', including creating your own interpreters
-- that make use of it, see "Polysemy.Final"
, Final
, embedFinal
-- * Lifting
, raise
, raiseUnder
, raiseUnder2
, raiseUnder3
, raise2Under
, raise3Under
, raise_
, subsume_
, insertAt
-- * Trivial Interpretation
, subsume
-- * Creating New Effects
-- | Effects should be defined as a GADT (enable @-XGADTs@), with kind @(*
-- -> *) -> * -> *@. Every primitive action in the effect should be its
-- own constructor of the type. For example, we can model an effect which
-- interacts with a tty console as follows:
--
-- @
-- data Console m a where
-- WriteLine :: String -> Console m ()
-- ReadLine :: Console m String
-- @
--
-- Notice that the @a@ parameter gets instantiated at the /desired return/
-- /type/ of the actions. Writing a line returns a @()@, but reading one
-- returns 'String'.
--
-- By enabling @-XTemplateHaskell@, we can use the 'makeSem' function
-- to generate smart constructors for the actions. These smart constructors
-- can be invoked directly inside of the 'Sem' monad.
--
-- > makeSem ''Console
--
-- results in the following definitions:
--
-- @
-- writeLine :: 'Member' Console r => String -> 'Sem' r ()
-- readLine :: 'Member' Console r => 'Sem' r String
-- @
--
-- Each of these generated definitions make use of 'send' in order to perform
-- the corresponding action of the effect. If you don't want to use
-- Template Haskell, you can write the necessary boilerplate yourself by
-- using 'send' directly.
--
-- Effects which don't make use of the @m@ parameter are known as
-- "first-order effects."
-- ** Higher-Order Effects
-- | Every effect has access to the @m@ parameter, which corresponds to the
-- 'Sem' monad it's used in. Using this parameter, we're capable of
-- writing effects which themselves contain subcomputations.
--
-- For example, the definition of 'Polysemy.Error.Error' is
--
-- @
-- data 'Polysemy.Error.Error' e m a where
-- 'Polysemy.Error.Throw' :: e -> 'Polysemy.Error.Error' e m a
-- 'Polysemy.Error.Catch' :: m a -> (e -> m a) -> 'Polysemy.Error.Error' e m a
-- @
--
-- where 'Polysemy.Error.Catch' is an action that can run an exception
-- handler if its first argument calls 'Polysemy.Error.throw'.
--
-- > makeSem ''Error
--
-- @
-- 'Polysemy.Error.throw' :: 'Member' ('Polysemy.Error.Error' e) r => e -> 'Sem' r a
-- 'Polysemy.Error.catch' :: 'Member' ('Polysemy.Error.Error' e) r => 'Sem' r a -> (e -> 'Sem' r a) -> 'Sem' r a
-- @
--
-- As you see, in the smart constructors, the @m@ parameter has become @'Sem' r@.
, send
, makeSem
, makeSem_
-- * Combinators for Interpreting First-Order Effects
, interpret
, intercept
, reinterpret
, reinterpret2
, reinterpret3
, rewrite
, transform
-- * Combinators for Interpreting Higher-Order Effects
, interpretH
, interceptH
, reinterpretH
, reinterpret2H
, reinterpret3H
-- * Kind Synonyms
, Effect
, EffectRow
-- * Tactics
-- | Higher-order effects need to explicitly thread /other effects'/ state
-- through themselves. Tactics are a domain-specific language for describing
-- exactly how this threading should take place.
--
-- The first computation to be run should use 'runT', and subsequent
-- computations /in the same environment/ should use 'bindT'. Any
-- first-order constructors which appear in a higher-order context may use
-- 'pureT' to satisfy the typechecker.
, Tactical
, WithTactics
, getInitialStateT
, pureT
, runTSimple
, bindTSimple
, runT
, bindT
, getInspectorT
, Inspector (..)
) where
import Polysemy.Final
import Polysemy.Internal
import Polysemy.Internal.Combinators
import Polysemy.Internal.Kind
import Polysemy.Internal.Tactics
import Polysemy.Internal.TH.Effect