Modification of State Transformer

Tom Pledger Tom.Pledger@peace.com
Fri, 9 Aug 2002 08:52:15 +1200


Shawn P. Garbett writes:
 :
 | What I want is something like this, so that the state transformer has a 
 | generic state type: 
 | 
 | newtype St a s = MkSt (s -> (a, s))
 | 
 | apply             :: St a s -> s -> (a, s)
 | apply (MkSt f) s  = f s
 | 
 | instance Monad St where
 |   return x  = MkSt f where f s = (x,s)
 |   p >>= q   = MkSt f where f s = apply (q x) s'
 |                                  where (x, s') = apply p s
 | -----------------------------------------------------------
 | The trouble occurs on the instance line
 |     Couldn't match `*' against `* -> *'
 |         Expected kind: (* -> *) -> *
 |         Inferred kind: (* -> * -> *) -> *

Let's compare your declaration of St with the type signatures in class
Monad.

    class Monad m where
        return :: a -> m a
        (>>=)  :: m a -> (a -> m b) -> m b
        -- etc.

If we instantiate m as St, we get a type of   a -> St a   for return,
which lacks the state variable s.  In turn, s corresponds to the third
* in the inferred kind in the error message.

Try partially applying St to its state variable, and declaring a Monad
instance of that partial application, which will have the right kind
*->*.

Regards,
Tom