如何在Haskell中使用State monad编号列表项?

时间:2019-05-29 12:19:30

标签: haskell monads state-monad

问题:

我正试图了解

有点不明白我该如何使用它,我正在寻找一些例子。

假设我要实现功能let dataSet = PieChartDataSet() // provide your own dataSet.label = "My Label" // or, no label dataSet.label = ""

[()] -> [Int]

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

如何使用numerate :: [()] -> [Int] 来做到这一点?

预期的行为:

State

谢谢!

1 个答案:

答案 0 :(得分:3)

我们可以实现一个State对象,该对象将递增状态并返回状态,例如:

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 = []}]}