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

Andrew Pimlott andrew at pimlott.net
Wed Nov 23 16:13:30 EST 2005


On Wed, Nov 23, 2005 at 02:03:22AM -0700, Fan Wu wrote:
> 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

Perhaps you were wondering, as I did when I read this, how

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

differs from

    lift (mplus m1' m2')

It helped me to rewrite mplus:

    mplus m1 m2 = S (\s ->  let m1' = runState s m1
                                m2' = runState s m2
                            in  ~(a, s') <- mplus m1' m2'
                                return (a, s'))

(If you reduce the first definition to this, you can verify that the
lazy pattern matches in the two correspond.)  So my question boils down
to, can you ever distinguish

    S (\s -> m >>= ~(a, s') -> return (a, s'))

from

    S (\s -> m)

using only exported operators?  I don't think so, because a subsequent
bind will do the lazy pattern match itself.  Did I miss something, or is
this use of ~ (and the subsequent poke, return) superfluous?

Andrew


More information about the Haskell-Cafe mailing list