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 .


Regards,
apfelmus

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to