effable
A data structure for emission plans
https://github.com/carlwr/effable#readme
| Stackage Nightly 2026-03-07: | 0.3.1.0 |
| Latest on Hackage: | 0.3.1.0 |
effable-0.3.1.0@sha256:0ed98714557152e2e7c1d5bcdd9a54ef42568367ed5b0922c0869d13df2e6337,2388Module documentation for 0.3.1.0
- Data
Effable
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
Why?
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.
Caveats and usage scope
-
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.
Intuition
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”?
Effable as in sayable or utterable.
Or, Eff-able as in able to be effected or effectuated - something with the potential to become effects.
Written by a human
During the development of this package, AI models were used extensively for discussions and feedback. All code and documentation however is authored by me (Carl), a human developer: no text (code; natural language) within this package/repo is direct output from an AI model.
Since I am not a native English speaker, any natural language is likely to feature language quirks. AI models were not asked to identify or rectify such.
The above should not be understood as any opinion or even preference of mine - I both use and value development with higher degrees of AI autonomy than what was used in this project.