I'm trying to run one of the most simple examples from the Haskell online book where you implement a stateful function modeling a stack of numbers. The code from the example I'm using is (http://learnyouahaskell.com/for-a-few-monads-more#state):
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)
Yet when trying to load it in Prelude I get:
state.hs:6:7: error:
Data constructor not in scope:
State :: ([a0] -> (a0, [a0])) -> State Stack Int
|
6 | pop = State $ \(x:xs) -> (x,xs)
| ^^^^^
state.hs:9:10: error:
Data constructor not in scope:
State :: ([Int] -> ((), [Int])) -> State Stack ()
|
9 | push a = State $ \xs -> ((),a:xs)
| ^^^^^
Failed, no modules loaded.
What am I missing??? Is this example somehow wrong?
I was just expecting to simply load the module with no errors. No clue what is wrong.
Somewhat surprisingly, the
Control.Monad.Statemodule does not contain a data constructor calledState. That would be the case if it simply defined– which it used to do in version 1 of the
mtllibrary, but doesn't anymore. Since version 2.0, the module only exports a type synonym calledState, which is actually re-exported fromControl.Monad.Trans.Stateand is implemented thus:The
Identitymonad makes this behave so thatm (a,s)is isomorphic to simply(a,s)by itself, so in the endStateT s Identity ais indeed isomorphic toState' s a. It is however more general:StateTis a monad transformer that can also be stacked on top of other monadic actions, such asIO.So you can't use a
Statevalue constructor, but you can usestatewhich behaves exactly asStatebehaved inmtl-1.1. (Except you can't pattern match on it, but you can still userunState.)