Государственная монада и learnyouahaskell.com - PullRequest
12 голосов
/ 14 марта 2012

Я читал Learn You Руководство Haskell по монаде состояния , но у меня возникли проблемы с его пониманием, так как пример стека не мог скомпилироваться. В руководстве он использовал следующий фрагмент кода:

import Control.Monad.State  

type Stack = [Int]

pop :: State Stack Int  
pop = State $ \(x:xs) -> (x,xs)  

push :: Int -> State Stack ()  
push a = State $ \xs -> ((),a:xs) 

Хотя я понимаю, что он должен делать, он не скомпилируется. Понятия не имею почему. Сообщение об ошибке:

Stack.hs:6:7: Not in scope: data constructor `State'

Stack.hs:9:10: Not in scope: data constructor `State'

Это не имеет смысла для меня, так как "State", насколько мне известно, на самом деле конструктор данных, определенный как

newtype State s a = State { runState :: s -> (a,s) }

Является ли руководство "неправильным", и если да, то как мне это исправить?

1 Ответ

18 голосов
/ 14 марта 2012

Как я уже упоминал в комментариях, вы должны использовать state вместо State.


Проблема в том, что State не является автономным типом данных (точнее, newtype), но это преобразователь StateT, применяемый к Identity монаде. На самом деле, это определяется как

type State s = StateT s Indentity

и поскольку это просто синоним type, он не может иметь конструктор State. Вот почему Control.Monad.State использует state.

...