----------------------------------------------------------------------------- -- | -- Module : Control.Effect.Machinery.Kind -- Copyright : (c) Michael Szvetits, 2020 -- License : BSD3 (see the file LICENSE) -- Maintainer : typedbyte@qualified.name -- Stability : stable -- Portability : portable -- -- This module defines some constraint synonyms and kinds that are used -- throughout this library, hopefully to increase the readability of the code -- at some points. ----------------------------------------------------------------------------- module Control.Effect.Machinery.Kind where -- base import Data.Kind (Constraint, Type) -- monad-control import Control.Monad.Trans.Control (MonadTransControl) -- transformers import Control.Monad.Trans.Class (MonadTrans) -- | The kind of monads. type SomeMonad = Type -> Type -- | The kind of effects, which are type classes with a monad type parameter at -- the end. type Effect = SomeMonad -> Constraint -- | The kind of monad transformers, also known as effect handlers or effect -- interpreters. type Transformer = SomeMonad -> Type -> Type -- | This type synonym indicates that an effect is handled by a specific monad -- transformer. type Handle (eff :: Effect) (t :: Transformer) m = eff (t m) -- | This constraint synonym indicates that a first-order effect is not handled -- by a specific monad transformer and must thus be delegated (\"lifted\") -- further down the monad transformer stack in order to find its associated -- handler. -- -- Roughly speaking, a first-order effect is a type class whose monad type -- parameter @m@ appears only in positive position when looking at the types of -- its corresponding class methods (e.g., @m@ appears only in the result type). -- -- An example of a first-order effect is the 'Control.Effect.State.State'' effect. type Lift (eff :: Effect) (t :: Transformer) m = (eff m, Monad (t m), MonadTrans t) -- | This constraint synonym indicates that a higher-order effect is not handled -- by a specific monad transformer and must thus be delegated (\"lifted\") -- further down the monad transformer stack in order to find its associated -- handler. -- -- Roughly speaking, a higher-order effect is a type class whose monad type -- parameter @m@ appears in negative position when looking at the types of its -- corresponding class methods (e.g., @m@ appears in the type of a method -- parameter). -- -- An example of a higher-order effect is the 'Control.Effect.Reader.Reader'' effect, -- since its class method 'Control.Effect.Reader.local'' has a parameter of -- type @m a@. type Control (eff :: Effect) (t :: Transformer) m = (eff m, Monad (t m), MonadTransControl t)