A data structure for emission plans
-- λ> import Data.Effable
-- λ> :info Effable
type Effable :: (* -> *) -> * -> *
newtype Effable m b
instance Semigroup (Effable m b)
instance Monoid (Effable m b)
instance Functor (Effable m)
instance Applicative (Effable m)
instance Monad (Effable m)
instance Alternative (Effable m)
instance MonadPlus (Effable m)
instance IsString b => IsString (Effable m b)Links:
An Effable m b is
-
a pure plan for the later emission of
bs -
a representation of an ordered sequence of
bs, each annotated with an emission wrapperm () -> m () -
emitted to its eventual result
m ()withrun(interpretation/elimination) -
fairly opaque
-
its constructor is not exported
-
observing it is only supported through
run/runWith
-
-
niche: see Caveats section
Compared to just working in the monadic m b context, Effable brings one particular distinguishing feature:
An
Effablecan undergo decoration with emission wrappers (wrap,wrapInside) after which it is still a pureEffable.
This means that even after having been modified with wrappers, or any other supported transformation...
-
...it is still a
Functor,ApplicativeandMonadinb -
...it can be transformed further and combined into more complex structures with
<>
Emission wrappers can be applied to granular constituents of an Effable as the user code is building it. The Effable machinery will track the wrappers behind-the-scenes through all supported transformations so that the eventual emission respects them.
-
Effectful predicates and emission wrappers typically run more than once when a plan is emitted.
-
these actions should yield the same value across evaluations, otherwise the inclusion of branches will be inconsistent
-
therefore,
Effableis only suitable when these actions are read-like (return the same value over repeated evaluations and are free of externally observable side-effects)
-
- The nesting of combinators and use of
<*>and>>=will grow the internalEffablerepresentation, and the number of times actions are run at emission, combinatorially.
Effables are kept pure through all supported transformations by representing all possible outcomes of actions that affect structure. Running the actions is deferred to emission time. This comes with the cost of the internal representation carrying a complexity proportional to all possible outcomes.
Metaphorically, Effable is the many-worlds interpretation of actions meaning actions can be represented without them interacting with the actual world (= purity) and its representation is not collapsed to an outcome until it is observed (= run).
Effable as in sayable or utterable.
Or, Eff-able as in able to be effected or effectuated - something with the potential of becoming effects.
AI tools were used extensively during the development of this package - for exploration, discussions, and feedback. All code and documentation were however authored by me (Carl), a human developer: no text in this repository is direct output from an AI model.