-- BEGIN state.hs
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)
push :: Int -> State Stack ()
push x = State $ \xs -> ((), x:xs)
stackManip :: State Stack Int
stackManip = do
push 3
pop
pop
-- END state.hs
But when I try to load it into ghci I get the following errors:
Prelude> :load "/home/admi/.pe/state.hs"
[1 of 1] Compiling Main ( /home/admi/.pe/state.hs,
interpreted )
/home/admi/.pe/state.hs:6:6: Not in scope: data constructor `State'
/home/admi/.pe/state.hs:9:9: Not in scope: data constructor `State'
Failed, modules loaded: none.
Prelude>
Now, I'm not exactly sure how to read the documentation for
Control.Monad.State [2] but it seems that newtype State s a = State
{...} defines a constructor, or am I wrong on that point too? So,
what am I missing here? In case it matters, I am using mtl-2.0.1.0
and ghci 6.12.3.
[1] http://learnyouahaskell.com/for-a-few-monads-more
[2]
http://cvs.haskell.org/Hugs/pages/libraries/mtl/Control-Monad-State.html
--
Adam Miezianko
> /home/admi/.pe/state.hs:6:6: Not in scope: data constructor `State'
> In case it matters, I am using mtl-2.0.1.0
> and ghci 6.12.3.
Learn You A Haskell was written when mtl-1.x was around. mtl-2.x has
incompatible changes, and this is one of them. State Stack Int is now an
alias for StateT Stack Identity Int, which in turn goes like
newtype StateT s m a = StateT{ runStateT :: s -> m (a,s) }
and you set m to Identity:
newtype Identity a = Identity{ runIdentity :: a }
So for example you have to rewrite pop as:
pop = StateT $ \(x:xs) -> Identity (x,xs)
Alternatively, hide away mtl-2.x and install mtl-1.x.