[Haskell-cafe] Re: Control.Exception.evaluate - 'correct definition' not so correct

apfelmus apfelmus at quantentunnel.de
Tue May 6 04:50:20 EDT 2008

Iavor Diatchki wrote:
> apfelmus wrote:
>> According to the monad law
>> f >>= return = f
>> every (>>=) ought to be strict in its first argument, so it indeed
>> seems that the implementation given in the documentation is wrong.
> From the monad law we can conclude only that "(>>= return)" is
> strict, not (>>=) in general.

Yes, I was too eager :)

> For example, (>>=) for the reader monad is not strict in its first
> argument:
> m >>= f = \r -> f (m r) r
> So, "(undefined >> return 2) = (return 2)"

In other words, we have

   undefined >>= const (return x) = return x

in the reader monad.

Concerning the folklore that  seq  destroys the monad laws, I would like
to remark that as long as we don't apply  seq  to arguments that are
functions, everything is fine. When  seq  is applied to functions,
already simple laws like

   f . id = f

are trashed, so it's hardly surprising that the monad laws are broken
willy-nilly. That's because  seq  can be used to distinguish between

   _|_ :: A -> B    and   \x -> _|_ :: A -> B

although there shouldn't be a semantic difference between them.

But it's true that in the case of  evaluate , the monad laws are screwed
up. The third equivalence would give

   evaluate _|_ >>= return  ==> (return $! _|_) >>= return
                            ==> _|_ >>= return

and hence

   evaluate _|_ = _|_

which contradicts the first equivalence. In other words, it seems that
in the presence of  evaluate , the monad laws for  IO  are broken if we
allow  seq  on values of type  IO .


More information about the Haskell-Cafe mailing list