Ralph, > you said that `fail' intentionally calls `error' in the IO monad > because it corresponds to pattern matching failure. I would buy this > argument if `fail' were used only internally. But it is exposed to the > user: she or he is free to call `fail'. Now, in the list > monad `fail s' > corresponds to failure, in an exception monad `fail s' probably > corresponds to raising an exception. Since IO is an exception monad, > I would expect that `fail' invokes `ioError' so that I am able to > handle this failure using catch. Or to make a long story > short: `fail = > error' is simply not as flexible as `fail = ioError ...'. So > what about > > > instance Monad IO where > > return = ... > > (>>=) = ... > > fail s = ioError (failError s) > > where a new primitive `failError' is used instead of `userError'. What you say is not unreasonable, but it is debatable. After all, the user can always call ioError; s/he dosen't *have* to call fail. The only time you *have* to call fail is on a pattern match failure, and the way it is now we uniformly get a run-time error when that happens. Whether it's in a monad or not. As you probably know, GHC and Hugs now support an exception mechanism which lets you recover from calls to 'error' -- but of course that's not in H98. Anyway, at this stage in the game I don't want to fiddle without dire need, and the need doesn't seem dire. Sorry. Simon