Safe Haskell | None |
---|---|
Language | Haskell2010 |
Yael.Eff
Description
Yael is an effect system that models effects as records. This module contains the core functionality needed to define and use effects.
In Yael, each effect is a record, paremeterized by a Monad
, m
. For example
data MyEffect m = MyEffect { _myMethod1 :: String -> m Bool , _myMethod2 :: m Int -> m [Int] }
Each field in an effect record is a "method" of that effect. Methods after often
functions, but they don't have to be. They can be of the form `m a` for some a
, or
they can simply not refer to m
at all. As seen in MyEffect
, methods can be
first-order, meaning that m
only appears in the result of a functional method, or
they can be higher order, meaning that m
appears in the arguments of a functional
method. Most methods are first-order, but higher-order methods are useful to represent
effects that can wrap other effectful code, for example when working with transactional
data
Synopsis
- data EffT (f :: (* -> *) -> *) (m :: * -> *) (a :: *)
- pattern EffT :: (f m -> m a) -> EffT f m a
- runEffT :: forall f m a. EffT f m a -> f m -> m a
- liftEffT :: (f m -> m a) -> EffT f m a
- shareEffT :: f m -> (Lower f m m -> EffT f m a) -> m a
- withEffT :: HasEff g f m => (forall n. Monad n => g n -> n a) -> EffT f m a
- withEffT' :: HasEff g f m => (forall n. Monad n => Lower f m n -> g n -> n a) -> EffT f m a
- withEffT'' :: HasEff g f m => (forall n. Monad n => Lower f m n -> Raise f m n -> g n -> n a) -> EffT f m a
- type Lower f m n = EffT f m ~> n
- type Raise f m n = n ~> EffT f m
- type (~>) f g = forall x. f x -> g x
- localEffT :: Project f g => (g m -> g m) -> EffT f m a -> EffT f m a
- mapEffT :: Monad m => (f m -> g m) -> EffT g m a -> EffT f m a
- type HasEff g f m = (Project f g, Monad m)
- type family HasEffs xs f m where ...
- type (:+) v effs = forall m f. HasEffs effs f m => EffT f m v
- data (a :<> b) (m :: * -> *) = (a m) :<> (b m)
- class Project (f :: (* -> *) -> *) g where
- newtype HigherOrder n (m :: * -> *) = HigherOrder {
- applyHigherOrder :: forall a. n a -> m a
Documentation
data EffT (f :: (* -> *) -> *) (m :: * -> *) (a :: *) Source #
EffT
is a monad transformer which adds an effect (or collection of effects) f
to an underlying Monad
m
.
Instances
MonadBase s m => MonadBase s (EffT f m) Source # | |
MonadBaseControl s m => MonadBaseControl s (EffT f m) Source # | |
MonadTrans (EffT f) Source # | |
Monad m => Monad (EffT f m) Source # | |
Functor m => Functor (EffT f m) Source # | |
Applicative m => Applicative (EffT f m) Source # | |
Alternative m => Alternative (EffT f m) Source # | |
MonadIO m => MonadIO (EffT f m) Source # | |
MonadPlus m => MonadPlus (EffT f m) Source # | |
MonadThrow m => MonadThrow (EffT f m) Source # | |
MonadCatch m => MonadCatch (EffT f m) Source # | |
MonadMask m => MonadMask (EffT f m) Source # | |
MonadUnliftIO m => MonadUnliftIO (EffT f m) Source # | |
type StM (EffT f m) a Source # | |
runEffT :: forall f m a. EffT f m a -> f m -> m a Source #
Run an effectful computation of f
in m
by providing a particular
instantiation of that effect.
liftEffT :: (f m -> m a) -> EffT f m a Source #
Synonym for the EffT
constructor. Lift a computation in m
with access to the
effect f
into EffT f m
withEffT :: HasEff g f m => (forall n. Monad n => g n -> n a) -> EffT f m a Source #
Lift a first-order computation that is expressible wholly through g
into EffT
.
This is most commonly used to define convient method accessors generically in
EffT
.
Returning to the MyEffect
example above, we'll see that _myMethod1
has type
MyEffect m -> String -> m Bool
. The MyEffect m
paremeter is cumbersome to
work with, so we can use withEffT
:
myMethod1 :: (HasEff MyEffect f m) => String -> EffT f m Bool myMethod1 s = withEffT $ myEffect -> _myMethod1 myEffect s
withEffT' :: HasEff g f m => (forall n. Monad n => Lower f m n -> g n -> n a) -> EffT f m a Source #
Lift a higher-order computation in g
into EffT
.
withEffT'
is similar to withEffT
, but it provides an additional "lowering"
function that is useful for working with higher order computations. For example
myMethod2 :: (HasEff MyEffect f m) => EffT f m Int -> EffT f m [Int] myMethod2 m = withEffT' $ lower myEffect -> _myMethod2 myEffect (lower m)
withEffT'' :: HasEff g f m => (forall n. Monad n => Lower f m n -> Raise f m n -> g n -> n a) -> EffT f m a Source #
localEffT :: Project f g => (g m -> g m) -> EffT f m a -> EffT f m a Source #
Modify a computational context. Useful for attaching behavior to a specific
scope. Compare to local
in Control.Monad.Reader
mapEffT :: Monad m => (f m -> g m) -> EffT g m a -> EffT f m a Source #
Transform an entire effect context into a new context. Useful for resolving one effect in a context without resolving every effect.
type HasEff g f m = (Project f g, Monad m) Source #
Type synonym expressing that an g
is available for use within the wider
context f
type family HasEffs xs f m where ... Source #
Type synonym expressing that a set of effects xs
are all available within
the wider context f. xs
is expressed as a type level list, however
order does not matter.
type (:+) v effs = forall m f. HasEffs effs f m => EffT f m v infix 7 Source #
Syntactic sugar for first order computations with no additional constraints
on the effectful context f
or computational context m
.
Example:
myFunction :: String -> [Int] :+ '[MyEffect] myFunction s = do r1 <- myMethod1 s case r1 of True -> myMethod2 $ return 17 False -> return [17]
data (a :<> b) (m :: * -> *) infixr 9 Source #
Combinator for composing effects.
Constructors
(a m) :<> (b m) infixr 9 |
Instances
Project b c => Project (a :<> b) c Source # | |
Project (a :<> b) a Source # | |
(Show (a m), Show (b m)) => Show ((a :<> b) m) Source # | |
Generic ((a :<> b) m) Source # | |
Field1 ((a :<> b) m) ((a' :<> b) m) (a m) (a' m) Source # | |
Field2 ((a :<> b) m) ((a :<> b') m) (b m) (b' m) Source # | |
type Rep ((a :<> b) m) Source # | |
Defined in Yael.Eff type Rep ((a :<> b) m) = D1 (MetaData ":<>" "Yael.Eff" "yael-0.1.0.0-8MF7NMWA8H16SJ1eDsVuId" False) (C1 (MetaCons ":<>" (InfixI RightAssociative 9) False) (S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedStrict) (Rec0 (a m)) :*: S1 (MetaSel (Nothing :: Maybe Symbol) NoSourceUnpackedness NoSourceStrictness DecidedStrict) (Rec0 (b m)))) |
class Project (f :: (* -> *) -> *) g where Source #
Typeclass for extracting a specific effect from a larger context. It should generally not be necessary to implement your own instances of this class.
newtype HigherOrder n (m :: * -> *) Source #
Helper for deriving Generic on effects with polymorphic methods
Constructors
HigherOrder | |
Fields
|