
Yitzchak Gale wrote:
I wrote:
Prelude> let f .! g = ((.) $! f) $! g Prelude> let f = undefined :: Int -> IO Int Prelude> f `seq` 42 *** Exception: Prelude.undefined Prelude> ((>>= f) . return) `seq` 42 42 Prelude> ((>>= f) .! return) `seq` 42 42
Duncan Coutts wrote:
Perhaps I'm missing something but I don't see what's wrong.
The monad laws say that (>>= f) . return must be identical to f.
I thought it was: return x >>= f = f x so here the lhs is saturated, so will hit _|_ when the action is executed just as the rhs will. I think the problem you're encountering is just that the above law doesn't imply: (>>= f) . return = f in Haskell because the lhs is of the form \x -> _|_ whereas the rhs, which should really be of the form \x -> _|_, is actually _|_ already(!) so the _|_ has effectively been allowed to jump to the left of the arrow hence the "inequality" detected by seq. Perhaps a solution would be to force _|_ to respect the shape of the type, thus non-terminating values of type a -> b would be given the value \_ -> _|_ instead of _|_ ? Regards, Brian. -- http://www.metamilk.com