
Yes indeed. I'll have a go right away: - When an unsafePerformIO action is aborted (due, presumably, to an exception either thrown by or thrownTo the thread running it), the RTS puts the entire execution context of the IO code on ice, so if the closure is later re-entered no work will have been lost, and actions aren't executed twice unless the entire thing is executed twice. The implementation is somewhat involved, but this is the Right Thing; it makes the semantics of unsafePerformIO nearly identical to ordinary pure code with regards to exceptions.
This is perhaps a silly idea, but perhaps useful -- there should be a version of unsafePerformIO that always does the "right" thing with regards to exceptions. From that, the other unamb primitives can perhaps be built more obviously? Additionally, this implementation would be potentially useful to libraries beyond unamb. Cheers, S.