
2009/1/27 Matthijs Kooijman
Hi all,
I've been reading the gentle introduction to Haskell a bit more closely today and there a few things which I can't quite understand (presumably because they are typo's). I've found two issues with the "Using monads" section [1]. Not sure if this is the right place to report this, but there's probably somewhere here who can fix it :-)
The first one is in the state monad data type. It reads:
data SM a = SM (S -> (a,S)) -- The monadic type
I can't seem to find out what "S" is exactly here. It seems to be a universally quantified type variable, but then it should be lowercase. Considering that it is referred to later on as "s", I suspect this is a type?
I guess it's wrong. S should be the type of the state but then it should've been declared as a type variable. I think a more readable declaration could be: data SM s a = SM { runState :: s -> (a,s) }
Further on, a resource monad is described. Here, a lift1 function is given to allow one to lift a normal computation into a resource aware computation, with the following type signature:
lift1 :: (a -> b) -> (R a -> R b)
Mmmmhhh... this seems the signature of the liftM function, whose purpose is to make a function operate on monadic values instead of pure values. Notice that this is different from the "lift" function you described above. A computation is a monadic value (i.e. an object of the type "Monad m => m a") and the "lift" function wraps that value into a monad transformer, making it a new monadic value (i.e. an object of the type "MonadTrans t, Monad m => t m a").
A few lines down, the inc operation is defined as follows:
inc i = lift1 (i+1)
This is clearly wrong, as the expression "i+1" is not of the function type, as required by the signature of lift1 (i.e. a -> b).
To me, this seems wrong. Even without going into the semantics, it seems that the (i+1) expression does not satisfy the type of the first argument to lift1. I suspect this should have been:
inc = lift1 (+1)
You're right. Cristiano