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:
>   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
```