Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.

Commit

Permalink
Add foldError function to class PluckError
Browse files Browse the repository at this point in the history
  • Loading branch information
endgame committed May 3, 2024
1 parent cee9ea3 commit 08ce407
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
27 changes: 20 additions & 7 deletions src/Control/Monad/Error/Hoist.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
Expand Down Expand Up @@ -67,7 +68,7 @@ hoistError
=> (e -> e')
-> t a
-> m a
hoistError f t = inspectError t >>= either (throwError . f) pure
hoistError f = foldError (throwError . f) pure

-- | A version of 'hoistError' that operates on values already in the monad.
--
Expand Down Expand Up @@ -172,16 +173,28 @@ infixl 8 <!?>

-- | A class for plucking an error @e@ out of a partiality type @t@.
class PluckError e t m | t -> e where
inspectError :: t a -> m (Either e a)
pluckError :: t a -> m (Either e a)
default pluckError :: Applicative m => t a -> m (Either e a)
pluckError = foldError (pure . Left) (pure . Right)

foldError :: (e -> m r) -> (a -> m r) -> t a -> m r
default foldError :: Monad m => (e -> m r) -> (a -> m r) -> t a -> m r
foldError f g = either f g <=< pluckError

{-# MINIMAL pluckError | foldError #-}

instance (Applicative m, e ~ ()) => PluckError e Maybe m where
inspectError = pure . maybe (Left ()) Right
pluckError = pure . maybe (Left ()) Right
foldError f = maybe (f ())

instance Applicative m => PluckError e (Either e) m where
inspectError = pure
pluckError = pure
foldError = either

instance PluckError e (ExceptT e m) m where
inspectError = runExceptT
instance Monad m => PluckError e (ExceptT e m) m where
pluckError = runExceptT
foldError f g = either f g <=< runExceptT

instance Applicative m => PluckError e (Except e) m where
inspectError = pure . runExcept
pluckError = pure . runExcept
foldError f g = either f g . runExcept
2 changes: 1 addition & 1 deletion src/Control/Monad/Fail/Hoist.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ hoistFail
=> (e -> String)
-> t a
-> m a
hoistFail f t = inspectError t >>= either (fail . f) pure
hoistFail f = foldError (fail . f) pure

-- | Hoist computations whose error type is already 'String'.
hoistFail' :: (PluckError String t m, MonadFail m) => t a -> m a
Expand Down

0 comments on commit 08ce407

Please sign in to comment.