The module containing the AlloyA type-class for working with effectful functions
(of the type
a -> m a). This module is an analogue to Data.Generics.Alloy.Pure
that supports functions that result in a monadic or applicative functor type.
All the functions in this module have versions for
Applicative and for
Monad. They have the same behaviour, and technically only the
Applicative version is necessary, but since not all monads have
Applicative instances, the
Monad versions are provided for convenience.
- class AlloyA t o o' where
- type RecurseA f opT = forall t. AlloyA t opT BaseOpA => t -> f t
- makeRecurseA :: Applicative f => opT f -> RecurseA f opT
- makeRecurseM :: Monad m => opT m -> RecurseA m opT
- type DescendA f opT = forall t. AlloyA t BaseOpA opT => t -> f t
- makeDescendA :: Applicative f => opT f -> DescendA f opT
- makeDescendM :: Monad m => opT m -> DescendA m opT
- data BaseOpA m = BaseOpA
- baseOpA :: BaseOpA m
- data (t :-* opT) m = (t -> m t) :-* (opT m)
- type OneOpA t = t :-* BaseOpA
- type TwoOpA s t = s :-* (t :-* BaseOpA)
The Alloy type-class for effectful functions, to be used with sets of
operations constructed from
:-*. You are unlikely to need to
transform directly; instead use 'makeRecurseA'\/'makeRecurseM' and 'makeDescendA'\/'makeDescendM'.
The first parameter to the type-class is the type currently being operated on, the second parameter is the set of operations to perform directly on the type, and the third parameter is the set of operations to perform on its children (if none of the second parameter operations can be applied).
A type representing a monadic/applicative functor modifier function that applies the given ops (opT) in the given monad/functor (f) directly to the given type (t).
Given a set of operations (as described in the
makes a recursive modifier function that applies the operations directly to
the given type, and then to its children, until it has been applied to all
the largest instances of that type.
A type representing a monadic/applicative functor modifier function that applies the given ops (opT) in the given monad/functor (f) to the children of the given type (t).
Given a set of operations, makes a descent modifier function that applies the operation to the type's children, and further down, until it has been applied to all the largest instances of that type.
The terminator for effectful opsets. Note that all effectful opsets are the
same, and both can be used with the applicative functions or monad functions
in this module. Whereas there is, for example, both
there is only one terminator for the opsets,
BaseOpA, which should be used
regardless of whether you use
The type that extends an opset (opT) in the given
monad/applicative-functor (m) to be applied to the given type (t). This is
for use with the
AlloyA class. A set of operations that operates
Baz in the IO monad can be constructed so:
ops :: (Foo :-* Bar :-* Baz :-* BaseOpA) IO ops = doFoo :-* doBar :-* doBaz :-* baseOpA doFoo :: Foo -> IO Foo doBar :: Bar -> IO Bar doBaz :: Baz -> IO Baz
The monad/functor parameter needs to be given when declaring an actual opset, but must be omitted when using the opset as part of a type-class constraint such as:
f :: AlloyA a (Foo :-* Bar :-* Baz :-* BaseOpA) BaseOpA => a -> IO a f = makeRecurse ops
|(t -> m t) :-* (opT m)|
A handy synonym for a monadic/applicative opset with only one item, to use with