是否有一个 Monad 收集结果并“mappend”它们?

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 代码对我来说仍然很新鲜。

4ca*_*tle 6

WriterT单子变压器可用于建立与每个动作monoidal值。

您可以使用liftReader动作包装到WriterTmonad 转换器中,然后使用 将每个动作的结果移动到 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.