Как мне нумеровать элементы списка, используя Государственную монаду в Haskell? - PullRequest
2 голосов
/ 29 мая 2019

Проблема:

Я пытаюсь понять .

Немного застрял, чтобы понять, как я могу его использовать, и я ищу пример.

Допустим, я хочу реализовать функцию [()] -> [Int]:

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

Должен ли я сопоставить каждый элемент списка состоянию и затем сложить его?

Как я могу сделать это, используя State?

Ожидаемое поведение:

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

Спасибо!

1 Ответ

3 голосов
/ 29 мая 2019

Мы можем реализовать объект 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 = []}]}
...