Chr*_*ert 3 monads haskell functional-programming state-monad monoids
我有以下带有半组元素的 Reader 模式:
runFunction :: Reader Env Element
runFunction = do
a <- getA
b <- getB
c <- getC
return $ a <> b <> c
Run Code Online (Sandbox Code Playgroud)
哪里getA :: Reader Env Element
。
有没有办法:
runFunction = do
getA
getB
getC
Run Code Online (Sandbox Code Playgroud)
我觉得我经常看到这种模式,我命令式地链接 monadic 调用,最后它们变成了单个元素。
注意:我不想做,getA >>= getB >>= getC
因为getB
不是:: Element -> Reader Env Element
感觉就像一个 State Monad,它会用 自动修改状态<>
,但我不知道。
使用 monadic 代码对我来说仍然很新鲜。
该WriterT
单子变压器可用于建立与每个动作monoidal值。
您可以使用lift
将Reader
动作包装到WriterT
monad 转换器中,然后使用 将每个动作的结果移动到 monad 的环境中tell
,对动作进行排序,然后使用 将结果解包回单个Reader
动作execWriterT
。
这就是我的意思:
import Control.Monad.Writer
wrap :: (Monad m, Monoid w) => m w -> WriterT w m ()
wrap m = lift m >>= tell
unwrap :: (Monad m) => WriterT w m a -> m w
unwrap = execWriterT
runFunction :: Reader Env Element
runFunction = unwrap $ do
wrap getA
wrap getB
wrap getC
Run Code Online (Sandbox Code Playgroud)
如您所见,这可以推广到任何 monad,而不仅仅是Reader
.