Thank you to anyone who has already donated - your generous donations helped make three months of treatment possible.

My brother Nate continues to fight stage IV Hodgkin's lymphoma. He's just 31, with a wife and baby girl. They have no active income (since he's been unable to return to work), no insurance, and cannot afford the treatment he needs. Nate and his family need your help. Please consider a donation, every dollar helps. Thanks.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{-# LANGUAGE CPP #-}
-- | For when you gotta catch 'em all
--
-- Also defines an orphan 'Alternative' instance for 'IO'
module Pokemon (SomeException, Exception, pokemonException, tryPokemonIO) where

import Control.Applicative
#ifdef __GLASGOW_HASKELL__
import Control.Exception hiding (catch)
import System.Exit
import qualified Control.Exception (catch)
#else
-- Stub types and classes for Haskell98
type SomeException = IOError

class Exception e where
	toException :: e -> SomeException
	fromException :: SomeException -> Maybe e

instance Exception IOError where
	toException = id
	fromException = Just
#endif

-- | Describes the class of exceptions that should be caught when you
--   need to catch 'em all.
pokemonException :: SomeException -> SomeException
#ifdef __GLASGOW_HASKELL__
pokemonException e =
	let Just r =
		fmap rethrowArithException (fromException e) <|>
		fmap rethrowErrorCall (fromException e) <|>
		fmap rethrowExitCode (fromException e) <|>
		fmap rethrowArrayException (fromException e) <|>
		fmap rethrowAsyncException (fromException e) <|>
		fmap rethrowAssertionFailed (fromException e) <|>
		fmap rethrowDeadlock (fromException e) <|>
		fmap rethrowBlockedIndefinitelyOnSTM (fromException e) <|>
		fmap rethrowBlockedIndefinitelyOnMVar (fromException e) <|>
		fmap rethrowNestedAtomically (fromException e) <|>
		fmap rethrowNoMethodError (fromException e) <|>
		fmap rethrowRecUpdError (fromException e) <|>
		fmap rethrowRecConError (fromException e) <|>
		fmap rethrowRecSelError (fromException e) <|>
		fmap rethrowPatternMatchFail (fromException e) <|>
		Just e
	in
		r
	where
	rethrowArithException = throw :: ArithException -> a
	rethrowErrorCall = throw :: ErrorCall -> a
	rethrowExitCode = throw :: ExitCode -> a
	rethrowArrayException = throw :: ArrayException -> a
	rethrowAsyncException = throw :: AsyncException -> a
	rethrowAssertionFailed = throw :: AssertionFailed -> a
	rethrowDeadlock = throw :: Deadlock -> a
	rethrowBlockedIndefinitelyOnSTM = throw :: BlockedIndefinitelyOnSTM -> a
	rethrowBlockedIndefinitelyOnMVar = throw :: BlockedIndefinitelyOnMVar -> a
	rethrowNestedAtomically = throw :: NestedAtomically -> a
	rethrowNoMethodError = throw :: NoMethodError -> a
	rethrowRecUpdError = throw :: RecUpdError -> a
	rethrowRecConError = throw :: RecConError -> a
	rethrowRecSelError = throw :: RecSelError -> a
	rethrowPatternMatchFail = throw :: PatternMatchFail -> a
#else
-- Nothing to rethrow in Haskell98
pokemonException = id
#endif

-- | Catch 'em all and produce 'Either'
tryPokemonIO :: IO a -> IO (Either SomeException a)
tryPokemonIO io = fmap Right io
#ifdef __GLASGOW_HASKELL__
	`Control.Exception.catch`
#else
	`catch`
#endif
	(\e -> return $! Left $! pokemonException e)

-- If you catch one, do this instead
instance Alternative IO where
	empty = ioError (userError "IO Alternative empty")
	a <|> b = a
#ifdef __GLASGOW_HASKELL__
		`Control.Exception.catch`
#else
		`catch`
#endif
		(\e -> (return $! pokemonException e) >> b)