Get the stateful environment of the world at the moment the effect e is
to be run. Prefer pureT, runT or bindT instead of using this function
directly.
Get a natural transformation capable of potentially inspecting values
inside of f. Binding the result of getInspectorT produces a function that
can sometimes peek inside values returned by bindT.
This is often useful for running callback functions that are not managed by
polysemy code.
Run a monadic action in a Tactical environment. The stateful environment
used will be the same one that the effect is initally run in. Use bindT if
you'd prefer to explicitly manage your stateful environment.
Run a monadic action in a Tactical environment. The stateful environment
used will be the same one that the effect is initally run in.
Use bindTSimple if you'd prefer to explicitly manage your stateful
environment.
This is a less flexible but significantly simpler variant of runT.
Instead of returning a Sem action corresponding to the provided action,
runTSimple runs the action immediately.
Lift a kleisli action into the stateful environment. You can use
bindT to get an effect parameter of the form a -> m b into something
that can be used after calling runT on an effect parameter m a.
Lift a kleisli action into the stateful environment.
You can use bindTSimple to execute an effect parameter of the form
a -> m b by providing the result of a runTSimple or another
bindTSimple.
This is a less flexible but significantly simpler variant of bindT.
Instead of returning a Sem kleisli action corresponding to the
provided kleisli action, bindTSimple runs the kleisli action immediately.
Tactical is an environment in which you're capable of explicitly
threading higher-order effect states. This is provided by the (internal)
effect Tactics, which is capable of rewriting monadic actions so they run
in the correct stateful environment.
Inside a Tactical, you're capable of running pureT, runT and bindT
which are the main tools for rewriting monadic stateful environments.
For example, consider trying to write an interpreter for
Resource, whose effect is defined as:
Here we have an m a which clearly needs to be run first, and then
subsequently call the a -> m () and a -> m b arguments. In a Tactical
environment, we can write the threading code thusly:
Bracket alloc dealloc use -> do
alloc' <- runT alloc
dealloc' <- bindT dealloc
use' <- bindT use
The f type here is existential and corresponds to "whatever
state the other effects want to keep track of." f is always
a Functor.
alloc', dealloc' and use' are now in a form that can be
easily consumed by your interpreter. At this point, simply bind
them in the desired order and continue on your merry way.
We can see from the types of dealloc' and use' that since they both
consume a f a1, they must run in the same stateful environment. This
means, for illustration, any puts run inside the use
block will not be visible inside of the dealloc block.
Power users may explicitly use getInitialStateT and bindT to construct
whatever data flow they'd like; although this is usually unnecessary.