我坚持跟随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))
它不起作用,但我不明白为什么?还有其他方法可以实现这样的功能吗?
答案 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吗?你的代码似乎很好,你能提供你使用的吗?你得到了什么样的不端行为?