@@ -1,6 +1,34 @@
11{-# LANGUAGE DeriveDataTypeable #-}
22{-# LANGUAGE DeriveFunctor #-}
33
4+------------------------------------------------------------------------------
5+-- |
6+-- Module : Database.PostgreSQL.Simple.Ok
7+-- Copyright : (c) 2011-2012 Leon P Smith
8+-- License : BSD3
9+--
10+-- Maintainer : leon@melding-monads.com
11+-- Stability : experimental
12+--
13+-- The 'Ok' type is a simple error handler, basically equivalent to
14+-- @Either [SomeException]@. This type (without the list) was used to
15+-- handle conversion errors in early versions of postgresql-simple.
16+--
17+-- One of the primary reasons why this type was introduced is that
18+-- @Either SomeException@ had not been provided an instance for 'Alternative',
19+-- and it would have been a bad idea to provide an orphaned instance for a
20+-- commonly-used type and typeclass included in @base@.
21+--
22+-- Extending the failure case to a list of 'SomeException's enables a
23+-- more sensible 'Alternative' instance definitions: '<|>' concatinates
24+-- the list of exceptions when both cases fail, and 'empty' is defined as
25+-- 'Errors []'. Though '<|>' one could pick one of two exceptions, and
26+-- throw away the other, and have 'empty' provide a generic exception,
27+-- this avoids cases where 'empty' overrides a more informative exception
28+-- and allows you to see all the different ways your computation has failed.
29+--
30+------------------------------------------------------------------------------
31+
432module Database.PostgreSQL.Simple.Ok where
533
634import Control.Applicative
@@ -8,16 +36,15 @@ import Control.Exception
836import Control.Monad(MonadPlus(..))
937import Data.Typeable
1038
11−newtype ManyErrors = ManyErrors [SomeException]
12− deriving (Show, Typeable)
13−
14−instance Exception ManyErrors
15−
16−-- FIXME: [SomeException] should probably be a difference list
39+-- FIXME: [SomeException] should probably be something else, maybe
40+-- a difference list (or a tree?)
1741
1842data Ok a = Errors [SomeException] | Ok !a
1943 deriving(Show, Typeable, Functor)
2044
45+-- | Two 'Errors' cases are considered equal, regardless of what the
46+-- list of exceptions looks like.
47+
2148instance Eq a => Eq (Ok a) where
2249 Errors _ == Errors _ = True
2350 Ok a == Ok b = a == b
@@ -37,7 +64,6 @@ instance Alternative Ok where
3764 Errors _ <|> b@(Ok _) = b
3865 Errors as <|> Errors bs = Errors (as ++ bs)
3966
40−
4167instance MonadPlus Ok where
4268 mzero = empty
4369 mplus = (<|>)
@@ -53,3 +79,10 @@ instance Monad Ok where
5379
5480 -- but *correct*, as this will throw an exception if you try to
5581 -- examine the exception.
82+
83+-- | a way to reify a list of exceptions into a single exception
84+
85+newtype ManyErrors = ManyErrors [SomeException]
86+ deriving (Show, Typeable)
87+
88+instance Exception ManyErrors