如何在 Haskell 中使用 State monad 计算列表项?

How can I numerate list items using State monad in Haskell?

问题:

我正在努力理解

有点难以理解如何使用它,我正在寻找一些示例。

假设我想实现一个功能 [()] -> [Int]:

numerate :: [()] -> [Int]

我应该将列表的每个元素映射到状态然后折叠它吗?

如何使用 State 来实现?

预期行为:

numerate [(), (), (), (), ()]
-- [1, 2, 3, 4, 5] 

谢谢!

我们可以实现一个 State 对象来递增状态和 return 它,例如:

incState :: State Int Int
incState = modify (1+) >> get

然后我们可以 运行 这个 State Int Int 覆盖列表,例如:

numerate :: (Traversable t) => t a -> t Int
numerate = flip evalState 0 . traverse (const incState)

例如:

Prelude Control.Monad.State> numerate Nothing
Nothing
Prelude Control.Monad.State> numerate (Just 'a')
Just 1
Prelude Control.Monad.State> numerate (Just 0)
Just 1
Prelude Control.Monad.State> numerate [1,4,2,5]
[1,2,3,4]
Prelude Control.Monad.State> numerate [(), (), ()]
[1,2,3]

我们还可以使用其他可遍历结构,例如 Tree

Prelude Control.Monad.State Data.Tree> numerate (Node 'a' [Node 'b' [], Node 'c' []])
Node {rootLabel = 1, subForest = [Node {rootLabel = 2, subForest = []},Node {rootLabel = 3, subForest = []}]}