polysemy-research / polysemy-zoo

:monkey::panda_face: Experimental, user-contributed effects and interpreters for polysemy
BSD 3-Clause "New" or "Revised" License
70 stars 21 forks source link

Absorbing exceptions.MonadThrow and exceptions.MonadCatch #40

Closed adamConnerSax closed 5 years ago

adamConnerSax commented 5 years ago

So, I thought this would be an easy extension of the absorbMonadError but not so much. Or I'm missing something. The exceptions thing is quantified (?) over the exception type. So I'm having trouble getting all the types--the e I need to specify for Polysemy.Error vs. the e that is forall'd in exceptions. My attempt so far is this: https://github.com/adamConnerSax/glm-haskell/blob/master/src/Polysemy/ConstraintAbsorber/MonadCatch.hs but that's just at a random stopping point of trying quantified constraints and then not and then throwing things and then giving up. Anyway, ideas are welcome. If someone can point me in the right direction, or explain why it'll never work, that would be much appreciated.

KingoftheHomeless commented 5 years ago

Use SomeException as the error type. Here's a POC:

import qualified Polysemy.Error as P

instance Member (Error SomeException) r => MonadThrow (Sem r) where
  throwM e = P.throw (toException e)

instance Member (Error SomeException) r => MonadCatch (Sem r) where
  catch m h = m `P.catch` \e -> case fromException e of
    Just e' -> h e'
    _       -> P.throw e
adamConnerSax commented 5 years ago

Ah! Hadn’t tried that. Or thought if it. Thanks! Will try.

adamConnerSax commented 5 years ago

With a little fiddling that worked. Thanks! @isovector, would you like this added to the zoo? I think it belongs there, since it's just part of what Error can absorb. I can add some tests and submit a PR, though probably not until late this week or early next. I don't think it adds much in the way of dependencies but I know you like to keep things lean... Here's the latest (obviously not in the zoo right now. I just needed it for something else. but it's ready to drop in): https://github.com/adamConnerSax/glm-haskell/blob/master/src/Polysemy/ConstraintAbsorber/MonadCatch.hs Also, though it's beyond me without a lot more work, it might be interesting to see if we can absorb MonadMask which involves some sort of bracket. See generalBracket in https://hackage.haskell.org/package/exceptions-0.10.2/docs/Control-Monad-Catch.html.

isovector commented 5 years ago

@adamConnerSax I'm definitely interested. Is this a thing you think we should have in order for completeness, or because this was a problem you ran into and needed to write it to get real work done? Personally I've never used MonadCatch, so I'm not sure where the community stands on the utility of such things.

adamConnerSax commented 5 years ago

I needed it for some work because an external lib (sparse-linear-algebra) used it for error handling. I could've managed it other ways, of course, but I'm trying to Polysemy all the things! Also, since you have runErrorAsOther, it's particularly easy to manage by just translating the SomeException family into whatever I was already doing.
I've got it working now, for my case, but no isolated tests. When I get to that, I'll put it all in a PR for the zoo.

isovector commented 5 years ago

Sounds good. Let's merge it!

isovector commented 5 years ago

What's the status of this? @adamConnerSax

adamConnerSax commented 5 years ago

Sorry! I forgot all about this. I'll be able to get to it next week. Thanks for the reminder!

adamConnerSax commented 5 years ago

Hopefully resolved with https://github.com/polysemy-research/polysemy-zoo/pull/54