failure-0.2.0: Control/Failure.hs
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
-- | Type classes for returning failures.
--
-- Note: This module used to contain a lot more functionality, but I believe it
-- was unused functionality. If you want any of it back, just email me.
module Control.Failure
( -- * Type class
Failure (..)
-- * General exceptions
, exception
{-
-- * Wrapping failures
, WrapFailure (..)
-- * Convenience 'String' failure
, StringException (..)
, failureString
-- * Convert 'Failure's into concrete types
, Try (..)
, NothingException (..)
, NullException (..)
-}
) where
import Control.Exception (throwIO, Exception (toException), SomeException (..))
import Control.Monad.Trans.Error ()
import Control.Monad.Trans.Class (MonadTrans (lift))
class Monad f => Failure e f where
failure :: e -> f v
-- | Convert to a 'SomeException' via 'toException' before calling 'failure'.
exception :: (Exception e, Failure SomeException m) => e -> m a
exception = failure . toException
{-
class Failure e f => WrapFailure e f where
-- | Wrap the failure value, if any, with the given function. This is
-- useful in particular when you want all the exceptions returned from a
-- certain library to be of a certain type, even if they were generated by
-- a different library.
wrapFailure :: (forall eIn. Exception eIn => eIn -> e) -> f a -> f a
instance Exception e => WrapFailure e IO where
wrapFailure f m =
m `catch` \e@SomeException{} -> throwIO (f e)
class Try f where
type Error f
-- Turn a concrete failure into an abstract failure
try :: Failure (Error f) f' => f a -> f' a
-- | Call 'failure' with a 'String'.
failureString :: Failure StringException m => String -> m a
failureString = failure . StringException
newtype StringException = StringException String
deriving Typeable
instance Show StringException where
show (StringException s) = "StringException: " ++ s
instance Exception StringException
-}
-- --------------
-- base instances
-- --------------
instance Failure e Maybe where failure _ = Nothing
instance Failure e [] where failure _ = []
instance Failure e (Either e) where failure = Left
instance Exception e => Failure e IO where
failure = throwIO
-- | Instance for all monad transformers, simply lift the @failure@ into the
-- base monad.
instance (MonadTrans t, Failure e m, Monad (t m)) => Failure e (t m) where
failure = lift . failure
{-
-- not a monad or applicative instance Failure e (Either e) where failure = Left
data NothingException = NothingException
deriving (Show, Typeable)
instance Exception NothingException
instance Try Maybe where
type Error Maybe = NothingException
try Nothing = failure NothingException
try (Just x) = return x
instance Try (Either e) where
type Error (Either e) = e
try (Left e) = failure e
try (Right x) = return x
data NullException = NullException
deriving (Show, Typeable)
instance Exception NullException
instance Try [] where
type Error [] = NullException
try [] = failure NullException
try (x:_) = return x
-}