如何在Haskell中结合List和State Monad?

3
我希望基本上可以映射列表,并同时携带一些状态。我想结合列表和状态单子可能会让我到达那里。我尝试了一些东西,并发现我可能需要使用ListT。作为我的实际问题的简化版本,想象一下我想要实现sum函数,同时还要返回原始列表的修改版本。这或类似于我想象中的样子:
sum' :: ListT (State Int) Int
sum' = do
    lift $ put 0
    x <- [1,2,3]
    lift $ modify (+x)
    return $ x + 1

我还不理解正常列表单子的语法如何转换为ListT单子。我不能简单地执行x <- [1,2,3],因为箭头右侧需要类型为ListT (State Int) t0x <- return [1,2,3]可以编译(即使编译器不会抱怨此行),但是它将整个列表放入x中,而不是每个元素。
如何让这个工作?

你想要 ssum xs = execState (traverse (modify . (+)) xs) 0 吗? - effectfully
不幸的是,每当有人谈论ListT时,你真的必须问一下“哪一个?”,因为有几个非常不同的版本表现出截然不同的行为。 - dfeuer
1个回答

4
    x <- ListT $ return [1,2,3]

或者

    x <- msum $ return <$> [1,2,3]
  • ListT.return 只是有意识地将一个列表结构注入到一个经过列表转换的单子堆栈中。

  • msum 利用了 ListT 是变换器,将一个单子映射到自由 MonadPlus 单子群上的事实。

will do the trick.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接