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?
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.
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).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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With