gpt4 book ai didi

haskell - 如何使用 StateT、ContT 和 ReaderT 创建 monad?

转载 作者:行者123 更新时间:2023-12-03 21:58:49 33 4
gpt4 key购买 nike

如何创建一个使用 State、Cont 和 Reader 转换器的 monad?我想阅读一个环境,并更新/使用状态。但是,我也想暂停/中断操作。例如,如果满足某个条件,则状态保持不变。

到目前为止,我有一个使用 ReaderT 和 StateT 的 monad,但我不知道如何包含 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 需要 kind * -> *?...我淹没在类型中,需要解释。 Pause 必须采用什么形式,一个函数? ContT如何整合?最终,我打算将 Cont 用于控制结构。

最佳答案

MonadReaderMonadState 不同,MonadCont 类型类takes only one parameter .由于该参数 m 必须是 Monad,因此它必须具有类型 * -> *

在派生子句中,您需要 MonadCont, 而不是 MonadCont Pause

在回答后续问题时添加:

继续 is defined as:

newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }

请注意,newtype M r 定义中的 r 作为最终 (a) 参数传递给 ContT。插入变量,你有

ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}

这提供了一个计算上下文,您可以在其中操作 StateType,并使用定界延续。最终,您将构造一个 ContT Bool (State StateType) Bool。然后您可以运行延续(使用 evalContT ),并返回到更简单的 State StateType 上下文。 (实际上,您可以在程序的同一部分解包所有 3 个 monad 转换器。)

关于haskell - 如何使用 StateT、ContT 和 ReaderT 创建 monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53403001/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com