I was reading Learn You a Haskell’s guide on the state monad, but I had trouble understanding it since the stack example couldn’t compile. In the guide, he used the following piece of code:
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)
While I understand what it’s supposed to do, it won’t compile. I have no idea why. The error message is:
Stack.hs:6:7: Not in scope: data constructor `State'
Stack.hs:9:10: Not in scope: data constructor `State'
This makes no sense to me, since “State” is, to my knowledge, in fact a data constructor, defined as
newtype State s a = State { runState :: s -> (a,s) }
Is the guide “wrong”, and if so, how do I fix it?
As I mentioned in comments, you ought to use
stateinstead ofState.The problem is that
Stateis not standalone data type (or rathernewtype), but it is theStateTtransformer applied toIdentitymonad. Actually, it’s defined asand because it’s just
typesynonym, it cannot haveStateconstructor. That’s whyControl.Monad.Stateusesstate.