attempt, and so on
raiseError(e).flatMap(f) == raiseError(e)
raiseError(e).handleErrorWith(_ => fa) == fa
IO is duplicitous, it's hiding the fact that errors can and do occur, no?
That's an entirely orthogonal discussion
MonadError[F, E]and you already know how to do a large class of things with it
onErroron monad error