
Hi, Apologies for referring to this old thread... I rearranged the code a little bit while experimenting but retained the same behaviour: Prelude> let f = undefined :: Int -> IO Int Prelude> (f 3 >> f 3) `seq` 42 42 Prelude> (f 3) `seq` 42 *** Exception: Prelude.undefined I think this makes it a little simpler for me to see the issue here. Simply, 'undefined >> undefined' is a bit more defined than simply 'undefined'. Just like 'undefined:undefined' is at least a non-empty list; which can be matched by (_:_) for example. This explains the differing behaviour of the two seemingly equivalent actions above. So I think the above behaviour is more to do with how shallow seq is, as others have probably already shown (but much of the rest of the thread is beyond me). Prelude> undefined `seq` 5 *** Exception: Prelude.undefined Prelude> (undefined:undefined) `seq` 5 5 Aaron (relative newbie)
On 1/23/07, Brian Hulley
wrote: Brian Hulley wrote:
Brian Hulley wrote:
Yitzchak Gale wrote:
I wrote:
> Prelude> let f = undefined :: Int -> IO Int > Prelude> f `seq` 42 > *** Exception: Prelude.undefined > Prelude> ((>>= f) . return) `seq` 42 > 42 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.
Ooops! But that does not mean the equation holds because for example
Prelude> (return 3 >>= f) `seq` 42 42 Prelude> (f 3) `seq` 42 *** Exception: Prelude.undefined
In the lhs you only hit _|_ when the composite (>>=) action is actually being executed whereas in the rhs you hit _|_ when computing the function which will return the action to execute so there is difference.
Brian. -- http://www.metamilk.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe