How do I create a monad which uses State, Cont, and Reader transformers? I would like to read an environment, and update/use state. However, I would also like to pause/interrupt the action. For example, if a condition is met, the state remains unchanged.
So far I have a monad using ReaderT and StateT, but I cannot work out how to include ContT:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Cont
-- reader environment
type In = Integer
-- cont: if true then pause, else continue
type Pause = Bool
-- state environment:
newtype StateType = StateType { s :: Integer }
newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
deriving ( Functor, Applicative, Monad
, MonadReader In
, MonadCont Pause
, MonadState StateType
)
-- run monadic action
runM :: In -> Pause -> StateType -> M r -> StateType
runM inp pause initial act
= runIdentity -- unwrap identity
$ flip execStateT initial -- unwrap state
$ flip runContT pause -- unwrap cont
$ flip runReaderT inp -- unwrap reader
$ _unM act -- unwrap action
This gives the error:
* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|
Ok, but why does Pause
need kind * -> *
?... I'm drowning in types, in need of explanation. What form does Pause
have to take, a function? How does ContT integrate? Ultimately, I plan to use Cont for a control structure.
ContT Pause
isContT Bool
and it looks a bit weird since it's(a -> m Bool) -> m Bool
, which might or might not be what you want. – chiReaderT (ContT (StateT)))
. May be incorrect, been reading docs to confirm. ConcerningContT Bool
, I think this is the stem of my confusion. I originally looked at it likeReaderT
orStateT
which useIn
andStateType
respectively. What is(a -> m Bool) -> m Bool
? Seems more abstract thanStateType
or the Reader environment type. How does theContT
use the function inrunM
? – dopamane