On 24 Nov 2004, at 18:28, John Goerzen wrote:
> I note, though, that "making an Either into a Monad" doesn't do
> anything
> to deal with asynchronous exceptions.
>
We may be talking at cross purposes here. If, by 'asynchronous
exceptions' you mean that exceptions may lurk arbitrarily deeply within
user defined data structures then using Either *does* solve this
problem.
Using 'Either' makes it crystal clear exactly where exception values
can exist. Rather than being arbitrarily deep in the structure,
exceptions can only exist at the nodes that you choose to decorate with
Either: which, in the obvious usage pattern, is only the root node.
This doesn't mean that exceptions can't be *raised* at any depth, it
just means that deep exceptions are propagated. In other words, the
'Either' pattern will actually, as a side effect, force complete
evaluation when you check for exceptions. [To be clear: it will only do
this if you choose to use the usage pattern where only the root node is
decorated as 'Either' and your functions propagate the Either-ness]
Writing such code 'by hand' would involve a large amount of wrapping
and unwrapping (as you observed). That's all "making Either into a
Monad" will cure: it makes the wrapping and unwrapping of Lefts and
Rights a product of haskell's clever monadic syntax. It also makes you
choose an evaluation order, which removes non-determinism (the first
exception is the propagated one).
If that isn't what you meant by asynchronous exceptions then we are
indeed talking at cross-purposes!
Jules