KingoftheHomeless/in-other-words

Add an interpreter that does not use OpaqueExc for Error effect

Closed this issue · 1 comments

Since the Error effect can be interpreted as exceptions, one reasonable use case of Error is to mark codes that might throw exceptions, such as readFile:

readFile' :: (Eff (Embed IO) m, Eff (Error IOException) m) => FilePath -> m String
readFile' = embed . readFile

test :: IO (Either IOException String)
test = runM $ errorToIO $ readFile "testfile"

But because errorToErrorIO throws and catches the wrapper OpaqueExc instead of the exception itself, the underlying exception IOException won't actually get handled as one might want it to. I feel like there should be an interpreter that operates on the exception itself instead of OpaqueExc. Also, I'd like to argue that interpreting two identical Error e effect isn't really a common use case.

Sure, that's a good idea.

Also, I'd like to argue that interpreting two identical Error e effect isn't really a common use case.

It's unlikely for a user to intentionally have two identical Error e effects, yes, but identical Error effects could pop up regardless. Say some library offers an interpreter fooToIO :: MonadCatch m => FooToIOC m a -> m a which -- as part of its implementation -- uses a (hidden to the outside world) Error String effect interpreted using errorToIO.
If the OpaqueExc solution wasn't used, then if you use both fooToIO and your own Error String effect interpreted using errorToIO, then they will conflict with one another -- catching exceptions thrown by eachother. This would be a very nefarious bug source.