如何在 Haskell 中组合 List 和 State Monad
How to combine List and State Monad in Haskell
我想基本上映射一个列表,同时携带一些状态。我认为结合列表和状态 monad 可能会让我到达那里。我尝试了一些东西,发现我可能需要为此使用 ListT
。作为我的实际问题的简化版本,假设我想要实现 sum
函数,同时还返回原始列表的修改版本。这个或类似的是我想象的样子:
sum' :: ListT (State Int) Int
sum' = do
lift $ put 0
x <- [1,2,3]
lift $ modify (+x)
return $ x + 1
我还不明白常规列表 monad 的语法如何转换为 ListT monad。我不能简单地做 x <- [1,2,3]
,因为在箭头的右侧,需要输入 ListT (State Int) t0
。 x <- return [1,2,3]
编译(因为防止编译器抱怨这一行)但让我将整个列表放入 x,而不是每个元素。
我如何让它工作?
x <- ListT $ return [1,2,3]
或
x <- msum $ return <$> [1,2,3]
会成功的。
ListT . return
只是将列表结构感知注入到列表转换的 monad 堆栈中。
msum
使用 ListT
是将 monad 映射到其上的自由 MonadPlus
幺半群的变换器。
我想基本上映射一个列表,同时携带一些状态。我认为结合列表和状态 monad 可能会让我到达那里。我尝试了一些东西,发现我可能需要为此使用 ListT
。作为我的实际问题的简化版本,假设我想要实现 sum
函数,同时还返回原始列表的修改版本。这个或类似的是我想象的样子:
sum' :: ListT (State Int) Int
sum' = do
lift $ put 0
x <- [1,2,3]
lift $ modify (+x)
return $ x + 1
我还不明白常规列表 monad 的语法如何转换为 ListT monad。我不能简单地做 x <- [1,2,3]
,因为在箭头的右侧,需要输入 ListT (State Int) t0
。 x <- return [1,2,3]
编译(因为防止编译器抱怨这一行)但让我将整个列表放入 x,而不是每个元素。
我如何让它工作?
x <- ListT $ return [1,2,3]
或
x <- msum $ return <$> [1,2,3]
会成功的。
ListT . return
只是将列表结构感知注入到列表转换的 monad 堆栈中。msum
使用ListT
是将 monad 映射到其上的自由MonadPlus
幺半群的变换器。