Skip to content

Commit

Permalink
Merge pull request #10 from haskell-works/newhoggy/new-onExceptionM-a…
Browse files Browse the repository at this point in the history
…nd-onExceptionThrowM-functions

New onExceptionM and onExceptionThrowM functions
  • Loading branch information
newhoggy authored Jan 17, 2023
2 parents 8c95bfe + 254e184 commit deb389c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
2 changes: 2 additions & 0 deletions oops.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ common Glob { build-depends: Glob
common doctest { build-depends: doctest >= 0.16.2 && < 0.21 }
common doctest-discover { build-depends: doctest-discover >= 0.2 && < 0.3 }
common doctest-prop { build-depends: doctest-prop >= 0.2.0.1 && < 0.3 }
common exceptions { build-depends: exceptions }
common hedgehog-quickcheck { build-depends: hedgehog-quickcheck }
common hedgehog { build-depends: hedgehog }
common hspec { build-depends: hspec }
Expand All @@ -42,6 +43,7 @@ common project-config

library
import: base, project-config,
exceptions,
mtl,
QuickCheck,
transformers,
Expand Down
27 changes: 25 additions & 2 deletions src/Control/Monad/Oops.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ module Control.Monad.Oops
recoverM,
recoverOrVoidM,

onExceptionThrowM,
onExceptionM,

DV.CouldBeF (..),
DV.CouldBe (..),
DV.CouldBeAnyOfF,
Expand All @@ -71,8 +74,9 @@ import Data.Functor.Identity (Identity (..))
import Data.Variant (Catch, CatchF(..), CouldBe, CouldBeF(..), Variant, VariantF, preposterous)
import Data.Void (Void, absurd)

import qualified Data.Variant as DV
import qualified System.Exit as IO
import qualified Control.Monad.Catch as CMC
import qualified Data.Variant as DV
import qualified System.Exit as IO

-- | When working in some monadic context, using 'catch' becomes trickier. The
-- intuitive behaviour is that each 'catch' shrinks the variant in the left
Expand Down Expand Up @@ -292,3 +296,22 @@ recoverOrVoidM :: forall x e m. ()
=> ExceptT (Variant (x : e)) m Void
-> ExceptT (Variant e) m x
recoverOrVoidM f = either pure absurd =<< (fmap Right f & catchM @x (pure . Left))

-- | Catch an exception of the specified type 'x' and throw it as an error
onExceptionThrowM :: forall x e m a. ()
=> CMC.MonadCatch m
=> CMC.Exception x
=> MonadError (Variant e) m
=> CouldBeF e x
=> m a
-> m a
onExceptionThrowM = onExceptionM @x throwM

-- | Catch an exception of the specified type 'x' and call the the handler 'h'
onExceptionM :: forall x m a. ()
=> CMC.MonadCatch m
=> CMC.Exception x
=> (x -> m a)
-> m a
-> m a
onExceptionM h f = either h pure =<< CMC.try f

0 comments on commit deb389c

Please sign in to comment.