raiseIO# result looks wrong
primops.txt.pp includes the following note:
raiseIO#needs to be a primop, because exceptions in the
IOmonad must be precise - we don't want the strictness analyser turning one kind of bottom into another, as it is allowed to do in pure code.
But we do want to know that it returns bottom after being applied to two arguments, so that this function is strict in
f x y | x>0 = raiseIO blah | y>0 = return 1 | otherwise = return 2
I believe the "But we do" portion is, unfortunately, entirely wrong. From a user perspective, it is extremely strange to replace a precise exception with an imprecise one. That is, I strongly believe the above code should be considered lazy in
y. The function
f calculates an
IO action; the value of
y is only necessary to calculate that action if
x is non-positive.
We can, conservatively, say for certain that the second component of the result of
raiseIO# (i.e., the "return value") is bottom. We can also say, given
case raiseIO# e s of (# s', r #) -> q
q is dead (we could replace it by
(# s', undefined #)).