failure (empty) → 0.0.0
raw patch · 3 files changed
+128/−0 lines, 3 filesdep +basesetup-changed
Dependencies added: base
Files
- Control/Failure.hs +97/−0
- Setup.lhs +7/−0
- failure.cabal +24/−0
+ Control/Failure.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}+-- | Type classes for returning failures.+module Control.Failure+ ( -- * Type classes+ Failure (..)+ , FunctorFailure+ , ApplicativeFailure+ , MonadFailure+ -- * Wrapping failures+ , WrapFailure (..)+ -- * Convenience 'String' failure+ , StringException (..)+ , failureString+ -- * Convert 'Failure's into concrete types+ , Try (..)+ , NothingException (..)+ , NullException (..)+ ) where++import Prelude hiding (catch)+import Control.Exception (throw, catch, Exception, SomeException (..))+import Data.Typeable (Typeable)+import Control.Applicative (Applicative, pure)++class Failure e f where+ failure :: e -> f v+class (Functor f, Failure e f) => FunctorFailure e f+class (Applicative f, Failure e f) => ApplicativeFailure e f+class (Monad f, Applicative f, Failure e f) => MonadFailure e f++-- These introduce the need to use undecidables.+-- However, since they are merely type class synonyms, this is acceptable.+instance (Functor f, Failure e f) => FunctorFailure e f+instance (Applicative f, Failure e f) => ApplicativeFailure e f+instance (Monad f, Applicative f, Failure e f) => MonadFailure e f++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{} -> throw (f e)++class Try f where+ type Error f+ -- Turn a concrete failure into an abstract failure+ try :: ApplicativeFailure (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 Exception e => Failure e IO where+ failure = Control.Exception.throw++instance Failure e (Either e) where failure = Left++data NothingException = NothingException+ deriving (Show, Typeable)+instance Try Maybe where+ type Error Maybe = NothingException+ try Nothing = failure NothingException+ try (Just x) = pure x++instance Try (Either e) where+ type Error (Either e) = e+ try (Left e) = failure e+ try (Right x) = pure x++data NullException = NullException+ deriving (Show, Typeable)+instance Try [] where+ type Error [] = NullException+ try [] = failure NullException+ try (x:_) = pure x
+ Setup.lhs view
@@ -0,0 +1,7 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ failure.cabal view
@@ -0,0 +1,24 @@+name: failure+version: 0.0.0+Cabal-Version: >= 1.6+build-type: Simple+license: PublicDomain+author: Pepe Iborra, Michael Snoyman, Nicolas Pouillard+maintainer: pepeiborra@gmail.com+homepage: http://github.com/snoyberg/failure+description: A simple type class for success/failure computations.+synopsis: A simple type class for success/failure computations.+category: Control, Monads, Failure+stability: stable++Library+ buildable: True+ build-depends: base >= 4 && < 5+ ghc-options: -Wall++ exposed-modules:+ Control.Failure++source-repository head+ type: git+ location: git://github.com/snoyberg/failure.git