Copyright | (c) Samuel Schlesinger 2020 |
---|---|
License | MIT |
Maintainer | sgschlesinger@gmail.com |
Stability | experimental |
Portability | POSIX, Windows |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Control.Monad.Commander
Contents
Description
Synopsis
- data CommanderT state f a
- = Action (state -> f (CommanderT state f a, state))
- | Defeat
- | Victory a
- runCommanderT :: Monad m => CommanderT state m a -> state -> m (Maybe a)
- hoistToFunctor :: Functor g => (forall a. f a -> g a) -> CommanderT state f a -> CommanderT state g a
- hoistFromFunctor :: Functor f => (forall a. f a -> g a) -> CommanderT state f a -> CommanderT state g a
The CommanderT Monad
The CommanderT
monad is stateful and has the ability to backtrack.
data CommanderT state f a Source #
A CommanderT
action is a metaphor for a military commander. At each
step, we have a new Action
to take, or we could have experienced
Defeat
, or we can see Victory
. While a real life commander
worries about moving his troops around in order to achieve a victory in
battle, a CommanderT
worries about iteratively transforming a state
to find some value.
In more practical terms, a term of type CommanderT
can be thought of
as a backtracking, stateful computation which can either result in
a result being produced, or nothing being produced. It is a
Monad
for any base Functor
you want to use as the effect inside of
the stateful computation, similarly to the free monad.
Constructors
Action (state -> f (CommanderT state f a, state)) | |
Defeat | |
Victory a |
Instances
MonadTrans (CommanderT state) Source # | |
Defined in Control.Monad.Commander Methods lift :: Monad m => m a -> CommanderT state m a # | |
Functor f => Monad (CommanderT state f) Source # | |
Defined in Control.Monad.Commander Methods (>>=) :: CommanderT state f a -> (a -> CommanderT state f b) -> CommanderT state f b # (>>) :: CommanderT state f a -> CommanderT state f b -> CommanderT state f b # return :: a -> CommanderT state f a # | |
Functor f => Functor (CommanderT state f) Source # | |
Defined in Control.Monad.Commander Methods fmap :: (a -> b) -> CommanderT state f a -> CommanderT state f b # (<$) :: a -> CommanderT state f b -> CommanderT state f a # | |
Functor f => Applicative (CommanderT state f) Source # | |
Defined in Control.Monad.Commander Methods pure :: a -> CommanderT state f a # (<*>) :: CommanderT state f (a -> b) -> CommanderT state f a -> CommanderT state f b # liftA2 :: (a -> b -> c) -> CommanderT state f a -> CommanderT state f b -> CommanderT state f c # (*>) :: CommanderT state f a -> CommanderT state f b -> CommanderT state f b # (<*) :: CommanderT state f a -> CommanderT state f b -> CommanderT state f a # | |
MonadIO m => MonadIO (CommanderT state m) Source # | |
Defined in Control.Monad.Commander Methods liftIO :: IO a -> CommanderT state m a # | |
Functor f => Alternative (CommanderT state f) Source # | |
Defined in Control.Monad.Commander Methods empty :: CommanderT state f a # (<|>) :: CommanderT state f a -> CommanderT state f a -> CommanderT state f a # some :: CommanderT state f a -> CommanderT state f [a] # many :: CommanderT state f a -> CommanderT state f [a] # |
runCommanderT :: Monad m => CommanderT state m a -> state -> m (Maybe a) Source #
We can run a CommanderT
on some state and see if it has
a successful campaign.
hoistToFunctor :: Functor g => (forall a. f a -> g a) -> CommanderT state f a -> CommanderT state g a Source #
We can go from a non-Functor
to a Functor
inside of a CommanderT
action. This does the transformation "top to bottom", as opposed to
hoistFromFunctor
, which does it "bottom to top". If your natural
transformation is lessening, i.e. it trims branching structure, then you
probably want to use this function.
hoistFromFunctor :: Functor f => (forall a. f a -> g a) -> CommanderT state f a -> CommanderT state g a Source #
We can go from a Functor
to a non-Functor
inside of a CommanderT
action. This does the transformation "bottom to top", as opposed to
hoistToFunctor
, which does it "top to bottom". If your natural
transformation is increasing, i.e. it adds branching structure, then you
probably want to use this function.