Как мне создать монаду, которая использует преобразователи State, Cont и Reader?Я хотел бы прочитать окружение и обновить / использовать состояние.Тем не менее, я также хотел бы приостановить / прервать действие.Например, если условие выполнено, состояние остается неизменным.
Пока у меня есть монада, использующая ReaderT и StateT, но я не могу понять, как включить 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
Это дает ошибку:
* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|
Хорошо, но почему Pause
нужен вид * -> *
? ... Я тону в типах, нуждаюсь в объяснении.В какой форме должна принимать Pause
функция?Как ContT интегрируется?В конечном итоге я планирую использовать Cont для структуры управления.