[Haskell-cafe] questions on lazy pattern, StateT monad

Fan Wu wufan9418 at gmail.com
Wed Nov 23 04:03:22 EST 2005


Hi Haskell gurus,

I'm very puzzled on some code I saw in GHC Monad.StateT (which is
about state monad transformers) source and hope you can kindly give me
some insight into this.

newtype StateT s m a  = S (s -> m (a,s))

instance MonadPlus m => MonadPlus (StateT s m) where
  mzero             = lift mzero
  mplus m1 m2       = do s <- peek
                         let m1' = runState s m1
                             m2' = runState s m2
          ???????---->   ~(a,s') <- lift (mplus m1' m2')
                         poke s'
                         return a


To illustrate my puzzle, say m is of List type and

   runState s m1 = m1' = [(a1, s1)]
   runState s m2 = m2' = [(a2, s2)]

With the definition of lift (also in the StateT.hs file) as

   instance Trans (StateT s) where
      lift m            = S (\s -> do x <- m
                                      return (x,s))

I got

   lift (mplus m1' m2') = lift ([(a1,s1), (a2,s2)])
                        =  S (\s -> [ ((a1,s1),s), ((a2,s2),s)])

I'm puzzled over this line:

    ~(a,s') <- lift (mplus m1' m2')

I think ~(a,s') shall be the value of the (StateT s m a) which is
generated by "lift (mplus m1' m2')". My questions are

- why use lazy pattern?

- how is ~(a,s') extracted from (StateT s m a)? This looks like magic
to me. In the example I have (a1,s1) and (a2,s2) in the lifted monad,
but it seems (a,s') only represents one at a time. It looks like how
data is pulled out of a List monad.

Your help is highly appreciated.

Thanks,
Fan


More information about the Haskell-Cafe mailing list