如何在 Haskell 中使用 State monad 计算列表项?
How can I numerate list items using State monad in Haskell?
问题:
我正在努力理解 state-monad。
有点难以理解如何使用它,我正在寻找一些示例。
假设我想实现一个功能 [()] -> [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 = []}]}
问题:
我正在努力理解 state-monad。
有点难以理解如何使用它,我正在寻找一些示例。
假设我想实现一个功能 [()] -> [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 = []}]}