如何在两个monad之间共享状态?

时间:2011-11-04 18:29:42

标签: haskell monads state-monad

我坚持跟随monad问题:

假设我有一个标准的monad状态,其状态为S =(LS,RS)。我还有另一个monad:

newtype StateP a = StateP {runP :: S -> (a, RS)}

我想使用StateP执行一些计算,然后在状态monad中将状态与状态合并:

merge m :: StateP() -> State()
merge m = do
 s@(l,r) <- get
 put (l, snd (runP m s))

它不起作用,但我不明白为什么?还有其他方法可以实现这样的功能吗?

3 个答案:

答案 0 :(得分:2)

如果您的代码几乎正确,请尝试

merge :: StateP() -> State()
merge m = do
    s@(l,r) <- get
    put (l, snd (runP m s))

但你需要真正给我们更多细节。

答案 1 :(得分:1)

您可以使用monad转换器使用两个monad堆栈更明确地模拟这些需求:一个只能读取LS,另一个可以读取和写入LS

type ReadOnlyLS a  = ReaderT LS (State RS) a
type ReadWriteLS a = StateT LS (State RS) a

要在ReadOnlyLS内运行ReadWriteLS,我们只需要从最外层的状态层中提取LS,将其提供给内部计算的读取器层,然后将生成的计算提升回来进入外部monad:

merge :: ReadOnlyLS a -> ReadWriteLS a
merge m = get >>= lift . runReaderT m

答案 2 :(得分:0)

如何实现RunP的功能?你为它重新定义了一个monad实例并且有getP / putP吗?你的代码似乎很好,你能提供你使用的吗?你得到了什么样的不端行为?