graft-0.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Effect.Internal

Synopsis

The freer monad

data Freer f a where Source #

Constructors

Pure :: a -> Freer f a 
Impure :: f a -> (a -> Freer f b) -> Freer f b 

Instances

Instances details
Monad m => InterpretOneLayer Freer h m Source # 
Instance details

Defined in Effect.Internal

Methods

interpretOneLayer :: (forall b. Fixpoint h Freer b -> m b) -> Freer (Fixpoint h Freer) a -> m a Source #

Monad m => InterpretOneLayerState x Freer h m Source # 
Instance details

Defined in Effect.Internal

Methods

interpretOneLayerState :: (forall b. x -> Fixpoint h Freer b -> m (b, x)) -> x -> Freer (Fixpoint h Freer) a -> m (a, x) Source #

((), EffectInject (MonadErrorEffect e) ops) => MonadError e (AST ops) Source # 
Instance details

Defined in Effect.Error

Methods

throwError :: e -> AST ops a #

catchError :: AST ops a -> (e -> AST ops a) -> AST ops a #

((), EffectInject (MonadStateEffect s) ops) => MonadState s (AST ops) Source # 
Instance details

Defined in Effect.State

Methods

get :: AST ops s #

put :: s -> AST ops () #

state :: (s -> (a, s)) -> AST ops a #

(((), Monoid w), EffectInject (MonadWriterEffect w) ops) => MonadWriter w (AST ops) Source # 
Instance details

Defined in Effect.Writer

Methods

writer :: (a, w) -> AST ops a #

tell :: w -> AST ops () #

listen :: AST ops a -> AST ops (a, w) #

pass :: AST ops (a, w -> w) -> AST ops a #

((), EffectInject MonadFailEffect ops) => MonadFail (AST ops) Source # 
Instance details

Defined in Effect.Fail

Methods

fail :: String -> AST ops a #

((), EffectInject MonadIOEffect ops) => MonadIO (AST ops) Source # 
Instance details

Defined in Effect.IO

Methods

liftIO :: IO a -> AST ops a #

Applicative (Freer f) Source # 
Instance details

Defined in Effect.Internal

Methods

pure :: a -> Freer f a #

(<*>) :: Freer f (a -> b) -> Freer f a -> Freer f b #

liftA2 :: (a -> b -> c) -> Freer f a -> Freer f b -> Freer f c #

(*>) :: Freer f a -> Freer f b -> Freer f b #

(<*) :: Freer f a -> Freer f b -> Freer f a #

Functor (Freer f) Source # 
Instance details

Defined in Effect.Internal

Methods

fmap :: (a -> b) -> Freer f a -> Freer f b #

(<$) :: a -> Freer f b -> Freer f a #

Monad (Freer f) Source # 
Instance details

Defined in Effect.Internal

Methods

(>>=) :: Freer f a -> (a -> Freer f b) -> Freer f b #

(>>) :: Freer f a -> Freer f b -> Freer f b #

return :: a -> Freer f a #

((), EffectInject Bar ops) => MonadBar (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

bar :: (((a -> AST ops b) -> c) -> d) -> AST ops c Source #

((), EffectInject Baz ops) => MonadBaz (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

baz :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Foo ops) => MonadFoo (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

foo :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Quux ops) => MonadQuux (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

quux :: Either (IO x, (AST ops a, Bool)) [b -> AST ops a] -> AST ops a Source #

((), EffectInject MonadAccountsEffect ops) => MonadAccounts (AST ops) Source # 
Instance details

Defined in Examples.Account.AbstractDomain

((), EffectInject MonadMiniLangEffect ops) => MonadMiniLang (AST ops) Source # 
Instance details

Defined in Examples.Ltl.HigherOrder

Methods

push :: MiniLangValue -> AST ops () Source #

pop :: AST ops MiniLangValue Source #

echo :: String -> AST ops () Source #

if_ :: AST ops a -> AST ops a -> AST ops a Source #

while_ :: AST ops () -> AST ops () Source #

((), EffectInject MonadKeyValueEffect ops) => MonadKeyValue (AST ops) Source # 
Instance details

Defined in Examples.Ltl.Simple

Fixpoint functors

This is a generalisation/analogy with constructions like

data Fix = f (Fix f)

Here, f is of kind Type -> Type. The first insight is that this works for arbitrary kinds k, i.e. for any f :: k -> k. The second step is noting that for k = Type -> Type, we can also build something that alternates between to fs. This is that type:

newtype Fixpoint (f :: (Type -> Type) -> Type -> Type) (g :: (Type -> Type) -> Type -> Type) :: Type -> Type where Source #

Constructors

Fixpoint 

Fields

Instances

Instances details
((), EffectInject (MonadErrorEffect e) ops) => MonadError e (AST ops) Source # 
Instance details

Defined in Effect.Error

Methods

throwError :: e -> AST ops a #

catchError :: AST ops a -> (e -> AST ops a) -> AST ops a #

((), EffectInject (MonadStateEffect s) ops) => MonadState s (AST ops) Source # 
Instance details

Defined in Effect.State

Methods

get :: AST ops s #

put :: s -> AST ops () #

state :: (s -> (a, s)) -> AST ops a #

(((), Monoid w), EffectInject (MonadWriterEffect w) ops) => MonadWriter w (AST ops) Source # 
Instance details

Defined in Effect.Writer

Methods

writer :: (a, w) -> AST ops a #

tell :: w -> AST ops () #

listen :: AST ops a -> AST ops (a, w) #

pass :: AST ops (a, w -> w) -> AST ops a #

((), EffectInject MonadFailEffect ops) => MonadFail (AST ops) Source # 
Instance details

Defined in Effect.Fail

Methods

fail :: String -> AST ops a #

((), EffectInject MonadIOEffect ops) => MonadIO (AST ops) Source # 
Instance details

Defined in Effect.IO

Methods

liftIO :: IO a -> AST ops a #

((), EffectInject Bar ops) => MonadBar (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

bar :: (((a -> AST ops b) -> c) -> d) -> AST ops c Source #

((), EffectInject Baz ops) => MonadBaz (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

baz :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Foo ops) => MonadFoo (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

foo :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Quux ops) => MonadQuux (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

quux :: Either (IO x, (AST ops a, Bool)) [b -> AST ops a] -> AST ops a Source #

((), EffectInject MonadAccountsEffect ops) => MonadAccounts (AST ops) Source # 
Instance details

Defined in Examples.Account.AbstractDomain

((), EffectInject MonadMiniLangEffect ops) => MonadMiniLang (AST ops) Source # 
Instance details

Defined in Examples.Ltl.HigherOrder

Methods

push :: MiniLangValue -> AST ops () Source #

pop :: AST ops MiniLangValue Source #

echo :: String -> AST ops () Source #

if_ :: AST ops a -> AST ops a -> AST ops a Source #

while_ :: AST ops () -> AST ops () Source #

((), EffectInject MonadKeyValueEffect ops) => MonadKeyValue (AST ops) Source # 
Instance details

Defined in Examples.Ltl.Simple

(forall (h :: Type -> Type). Applicative (f h)) => Applicative (Fixpoint f g) Source # 
Instance details

Defined in Effect.Internal

Methods

pure :: a -> Fixpoint f g a #

(<*>) :: Fixpoint f g (a -> b) -> Fixpoint f g a -> Fixpoint f g b #

liftA2 :: (a -> b -> c) -> Fixpoint f g a -> Fixpoint f g b -> Fixpoint f g c #

(*>) :: Fixpoint f g a -> Fixpoint f g b -> Fixpoint f g b #

(<*) :: Fixpoint f g a -> Fixpoint f g b -> Fixpoint f g a #

(forall (h :: Type -> Type). Functor (f h)) => Functor (Fixpoint f g) Source # 
Instance details

Defined in Effect.Internal

Methods

fmap :: (a -> b) -> Fixpoint f g a -> Fixpoint f g b #

(<$) :: a -> Fixpoint f g b -> Fixpoint f g a #

(forall (h :: Type -> Type). Monad (f h)) => Monad (Fixpoint f g) Source # 
Instance details

Defined in Effect.Internal

Methods

(>>=) :: Fixpoint f g a -> (a -> Fixpoint f g b) -> Fixpoint f g b #

(>>) :: Fixpoint f g a -> Fixpoint f g b -> Fixpoint f g b #

return :: a -> Fixpoint f g a #

Interpreting fixpoint functors layer by layer

class InterpretOneLayer f g m where Source #

The idea of this class: If you have InterpretOneLayer f g m and InterpretOneLayer g f m, it's pretty easy to obtain a function

 interpretFixpoint ::
   (InterpretOneLayer f g m, InterpretOneLayer g f m) =>
   Fixpoint f g a ->
   m a
 fromFixpoint = interpretOneLayer fromFixpoint . unFixpoint

which calls the two interpretOneLayer functions mutually recursively.

Methods

interpretOneLayer :: (forall b. Fixpoint g f b -> m b) -> f (Fixpoint g f) a -> m a Source #

Instances

Instances details
Monad m => InterpretOneLayer Freer h m Source # 
Instance details

Defined in Effect.Internal

Methods

interpretOneLayer :: (forall b. Fixpoint h Freer b -> m b) -> Freer (Fixpoint h Freer) a -> m a Source #

Interpreting fixpoint functors layer by layer, statefully

We could be even more generic and re-use the machinery from the last section, if we're willing to stack another StateT monad transformer. I chose this presentation because it makes interpretOneLayerState easier to understand and use later on.

class InterpretOneLayerState x f g m where Source #

Methods

interpretOneLayerState :: (forall b. x -> Fixpoint g f b -> m (b, x)) -> x -> f (Fixpoint g f) a -> m (a, x) Source #

Instances

Instances details
Monad m => InterpretOneLayerState x Freer h m Source # 
Instance details

Defined in Effect.Internal

Methods

interpretOneLayerState :: (forall b. x -> Fixpoint h Freer b -> m (b, x)) -> x -> Freer (Fixpoint h Freer) a -> m (a, x) Source #

Effect types

type Effect = (Type -> Type) -> Type -> Type Source #

The kind of effects.

data JoinedEffects (ops :: [Effect]) :: Effect where Source #

A list of Effects, treated as a single Effect.

Constructors

JoinedEffectsHere :: op m a -> JoinedEffects (op ': ops) m a 
JoinedEffectsThere :: JoinedEffects ops m a -> JoinedEffects (op ': ops) m a 

Instances

Instances details
((), EffectInject (MonadErrorEffect e) ops) => MonadError e (AST ops) Source # 
Instance details

Defined in Effect.Error

Methods

throwError :: e -> AST ops a #

catchError :: AST ops a -> (e -> AST ops a) -> AST ops a #

((), EffectInject (MonadStateEffect s) ops) => MonadState s (AST ops) Source # 
Instance details

Defined in Effect.State

Methods

get :: AST ops s #

put :: s -> AST ops () #

state :: (s -> (a, s)) -> AST ops a #

(((), Monoid w), EffectInject (MonadWriterEffect w) ops) => MonadWriter w (AST ops) Source # 
Instance details

Defined in Effect.Writer

Methods

writer :: (a, w) -> AST ops a #

tell :: w -> AST ops () #

listen :: AST ops a -> AST ops (a, w) #

pass :: AST ops (a, w -> w) -> AST ops a #

((), EffectInject MonadFailEffect ops) => MonadFail (AST ops) Source # 
Instance details

Defined in Effect.Fail

Methods

fail :: String -> AST ops a #

((), EffectInject MonadIOEffect ops) => MonadIO (AST ops) Source # 
Instance details

Defined in Effect.IO

Methods

liftIO :: IO a -> AST ops a #

((), EffectInject Bar ops) => MonadBar (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

bar :: (((a -> AST ops b) -> c) -> d) -> AST ops c Source #

((), EffectInject Baz ops) => MonadBaz (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

baz :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Foo ops) => MonadFoo (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

foo :: ((AST ops a -> b) -> AST ops c) -> AST ops c Source #

((), EffectInject Quux ops) => MonadQuux (AST ops) Source # 
Instance details

Defined in Effect.THTests

Methods

quux :: Either (IO x, (AST ops a, Bool)) [b -> AST ops a] -> AST ops a Source #

((), EffectInject MonadAccountsEffect ops) => MonadAccounts (AST ops) Source # 
Instance details

Defined in Examples.Account.AbstractDomain

((), EffectInject MonadMiniLangEffect ops) => MonadMiniLang (AST ops) Source # 
Instance details

Defined in Examples.Ltl.HigherOrder

Methods

push :: MiniLangValue -> AST ops () Source #

pop :: AST ops MiniLangValue Source #

echo :: String -> AST ops () Source #

if_ :: AST ops a -> AST ops a -> AST ops a Source #

while_ :: AST ops () -> AST ops () Source #

((), EffectInject MonadKeyValueEffect ops) => MonadKeyValue (AST ops) Source # 
Instance details

Defined in Examples.Ltl.Simple

class EffectInject (op :: Effect) (ops :: [Effect]) | ops -> op where Source #

Is a given type of effects an element of a list of effect types?

In writing "reification" instances, a useful idiom is something like

instance EffectInject (MonadWriterEffect w) ops => MonadWriter (AST ops)

which will define "writer-like syntax" for all lists of effects that contain 'WriterEffect w'. This idiom is also the reason for the functional dependency in the class: ops must contain enough information to determine op.

Users of the library should't write instances of this type, as they're generated automatically. Also, "reification" instances like the one above aren't written by hand, usually. Macros like makeEffect do this.

Methods

effectInject :: op m a -> JoinedEffects ops m a Source #

Instances

Instances details
EffectInject op (op ': ops) Source # 
Instance details

Defined in Effect.Internal

Methods

effectInject :: forall (m :: Type -> Type) a. op m a -> JoinedEffects (op ': ops) m a Source #

EffectInject x ops => EffectInject x (y ': ops) Source # 
Instance details

Defined in Effect.Internal

Methods

effectInject :: forall (m :: Type -> Type) a. x m a -> JoinedEffects (y ': ops) m a Source #

Abstract syntax trees for a list of effect types

type AST ops = Fixpoint Freer (JoinedEffects ops) Source #

An abstract syntax tree which may use Effects of types ops

astInject :: EffectInject op ops => op (AST ops) a -> AST ops a Source #

Low-level convenience function to build the "singleton" AST corresponding to one effect.

Interpreting ASTs

class InterpretEffect m op where Source #

Write an instance of this class to define the "standard" interpretation of an effect type into a suitable domain.

If you want to use the function interpretAST, this class has to be implemented for all effect types you're using in your AST. In the normal case, you won't do this by hand, but generate the instance (and others) using a macro like makeEffect.

Compared to logics like Logic.Ltl, this is a low-level class; in the standard applications of these logics, you'll never have to directly interact with this class.

Methods

interpretEffect :: (forall b. AST ops b -> m b) -> op (AST ops) a -> m a Source #

Given a function that describes how to interpret ASTs and an effect, return the interpretation of the effect.

Instances

Instances details
((), MonadFail m) => InterpretEffect m MonadFailEffect Source # 
Instance details

Defined in Effect.Fail

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadFailEffect (AST ops) a -> m a Source #

((), MonadIO m) => InterpretEffect m MonadIOEffect Source # 
Instance details

Defined in Effect.IO

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadIOEffect (AST ops) a -> m a Source #

((), MonadBar m) => InterpretEffect m Bar Source # 
Instance details

Defined in Effect.THTests

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> Bar (AST ops) a -> m a Source #

((), MonadBaz m) => InterpretEffect m Baz Source # 
Instance details

Defined in Effect.THTests

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> Baz (AST ops) a -> m a Source #

((), MonadFoo m) => InterpretEffect m Foo Source # 
Instance details

Defined in Effect.THTests

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> Foo (AST ops) a -> m a Source #

((), MonadQuux m) => InterpretEffect m Quux Source # 
Instance details

Defined in Effect.THTests

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> Quux (AST ops) a -> m a Source #

((), MonadAccounts m) => InterpretEffect m MonadAccountsEffect Source # 
Instance details

Defined in Examples.Account.AbstractDomain

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadAccountsEffect (AST ops) a -> m a Source #

((), MonadMiniLang m) => InterpretEffect m MonadMiniLangEffect Source # 
Instance details

Defined in Examples.Ltl.HigherOrder

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadMiniLangEffect (AST ops) a -> m a Source #

((), MonadKeyValue m) => InterpretEffect m MonadKeyValueEffect Source # 
Instance details

Defined in Examples.Ltl.Simple

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadKeyValueEffect (AST ops) a -> m a Source #

((), MonadError e m) => InterpretEffect m (MonadErrorEffect e) Source # 
Instance details

Defined in Effect.Error

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadErrorEffect e (AST ops) a -> m a Source #

((), MonadState s m) => InterpretEffect m (MonadStateEffect s) Source # 
Instance details

Defined in Effect.State

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadStateEffect s (AST ops) a -> m a Source #

((), MonadWriter w m) => InterpretEffect m (MonadWriterEffect w) Source # 
Instance details

Defined in Effect.Writer

Methods

interpretEffect :: forall (ops :: [Effect]) a. (forall b. AST ops b -> m b) -> MonadWriterEffect w (AST ops) a -> m a Source #

data ConstraintList :: (a -> Constraint) -> [a] -> Type where Source #

A list of constraints, reified as a datatype. Matching on the constructors will bring the constraints in scope.

This trick is used in the functions interpretAST and interpretASTStateful: while deconstructing the JoinedEffects to obtain the individual effects to be interpreted through their InterpretEffect (or InterpretEffectStateful) instances, the instances are brought into scope by deconstructing a matching ConstraintList.

Constructors

ConstraintNil :: ConstraintList c '[] 
ConstraintCons :: c ty => ConstraintList c tys -> ConstraintList c (ty ': tys) 

class InterpretEffects m ops where Source #

The constraint that all effects ops are interpretable (in the sense of InterpretEffect) into m.

You should never have to manually write an instance of this class, it should always be inferred.

Instances

Instances details
InterpretEffects m ('[] :: [(Type -> Type) -> Type -> Type]) Source # 
Instance details

Defined in Effect.Internal

(InterpretEffect m op, InterpretEffects m ops) => InterpretEffects m (op ': ops) Source # 
Instance details

Defined in Effect.Internal

interpretAST :: (Monad m, InterpretEffects m ops) => AST ops a -> m a Source #

If all effect types in ops have an InterpretEffect m instance, this function will interpret the AST into m.

Interpreting ASTs, statefully

class InterpretEffectStateful (t :: Type -> Type) m op where Source #

Write an instance of this class to define the "statefully modified" interpretation of an effect type into a suitable domain. The intuition is that you interpret effects of type ops into the domain m, while also passing a state of type t x from step to step. This state will control how effects are actually implemented in m.

If you want to use the function interpretASTStateful, this class has to be implemented for all effect types in the AST you're using.

Compared to logics like Logic.Ltl, this is a low-level class; in the standard applications of these logics, you'll never have to directly interact with this class.

Methods

interpretEffectStateful :: (forall b y. t y -> AST ops b -> m (b, t y)) -> t x -> op (AST ops) a -> m (a, t x) Source #

Given a function that describes how to interpret ASTs statefully, a current "interpretation state", and an effect, return the stateful interpretation of the effect.

Instances

Instances details
MonadFail m => InterpretEffectStateful x m MonadFailEffect Source #

A "passthough" instance for WriterEffects: Modifications are applied in all nested positions of Listen and Pass, but don't actually change the semantics of any WriterEffect.

Instance details

Defined in Effect.Fail.Passthrough

Methods

interpretEffectStateful :: forall (ops :: [Effect]) x0 a. (forall b y. x y -> AST ops b -> m (b, x y)) -> x x0 -> MonadFailEffect (AST ops) a -> m (a, x x0) Source #

MonadIO m => InterpretEffectStateful x m MonadIOEffect Source #

A "passthough" instance for MonadIOEffects: Modifications don't change anything.

Instance details

Defined in Effect.IO.Passthrough

Methods

interpretEffectStateful :: forall (ops :: [Effect]) x0 a. (forall b y. x y -> AST ops b -> m (b, x y)) -> x x0 -> MonadIOEffect (AST ops) a -> m (a, x x0) Source #

MonadError e m => InterpretEffectStateful x m (MonadErrorEffect e) Source #

A "passthough" instance for MonadErrorEffects: Modifications are applied in all nested positions of CatchError, but don't actually change the semantics of any MonadErrorEffect.

Instance details

Defined in Effect.Error.Passthrough

Methods

interpretEffectStateful :: forall (ops :: [Effect]) x0 a. (forall b y. x y -> AST ops b -> m (b, x y)) -> x x0 -> MonadErrorEffect e (AST ops) a -> m (a, x x0) Source #

MonadWriter e m => InterpretEffectStateful x m (MonadWriterEffect e) Source #

A "passthough" instance for MonadWriterEffects: Modifications are applied in all nested positions of Listen and Pass, but don't actually change the semantics of any MonadWriterEffect.

Instance details

Defined in Effect.Writer.Passthrough

Methods

interpretEffectStateful :: forall (ops :: [Effect]) x0 a. (forall b y. x y -> AST ops b -> m (b, x y)) -> x x0 -> MonadWriterEffect e (AST ops) a -> m (a, x x0) Source #

(MonadPlus m, InterpretEffect m op, InterpretNextBind t m op) => InterpretEffectStateful (NextBind t) m op Source # 
Instance details

Defined in Logic.NextBind

Methods

interpretEffectStateful :: forall (ops :: [Effect]) x a. (forall b y. NextBind t y -> AST ops b -> m (b, NextBind t y)) -> NextBind t x -> op (AST ops) a -> m (a, NextBind t x) Source #

class InterpretEffectsStateful t m ops where Source #

The constraint that all effects ops are statefully interpretable with a state of type t into m (in the sense of InterpretEffectStateful).

You should never have to manually write an instance of this class, it should always be inferred.

Instances

Instances details
InterpretEffectsStateful t m ('[] :: [(Type -> Type) -> Type -> Type]) Source # 
Instance details

Defined in Effect.Internal

(InterpretEffectStateful t m op, InterpretEffectsStateful t m ops) => InterpretEffectsStateful t m (op ': ops) Source # 
Instance details

Defined in Effect.Internal

interpretASTStateful :: (Monad m, InterpretEffectsStateful t m ops) => t x -> AST ops a -> m (a, t x) Source #

If all effect types in ops have an InterpretEffectStateful t m instance, this function will interpret the AST, starting at a given initial "interpretation state" of type t x for some x.