Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data constructor error when implementing state monad?

Tags:

haskell

monads

I'm going through the state monad here and I'm trying to implement:

import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State

type Stack = [Int]

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

However I'm getting the following error:

"Data constructor not in scope:
    State :: ([t0] -> (t0, [t0])) -> State Stack Int
Perhaps you meant one of these:
    ‘StateT’ (imported from Control.Monad.State),
    variable ‘state’ (imported from Control.Monad.State)"

Am I missing something basic here?

like image 606
Babra Cunningham Avatar asked Dec 19 '22 09:12

Babra Cunningham


1 Answers

No you aren't. The tutorial is simplifying things a bit (or maybe it is just outdated - I don't go far back enough to know which of the two) is outdated. Control.Monad.State defines a monad transformer StateT. It also exports a simpler type synonym equivalent to what the tutorial is teaching you

type State s a = StateT s Identity a

However, that does mean that the constructor isn't State, it is StateT (and it has a generalized signature). Thankfully, you won't need to worry too much about that for now.

  • For constructing State, you can use the state function and pretend it has the signature state :: (s -> (a,s)) -> State s a (in reality, it has a more general signature - which you come across in error messages).
  • For de-constructing State, just use runState :: State s a -> s -> (a,s) instead of pattern matching.

From the example you gave:

import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State

type Stack = [Int]

pop :: State Stack Int
pop = state $ \(x : xs) -> (x, xs)
like image 114
Alec Avatar answered Feb 12 '23 02:02

Alec