d9e1762a2f07cb9670b8b32dc101c5d5a331c9d0
[ghc.git] / compiler / utils / Maybes.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 \begin{code}
7 module Maybes (
8         module Data.Maybe,
9
10         MaybeErr(..), -- Instance of Monad
11         failME, isSuccess,
12
13         orElse,
14         firstJust, firstJusts,
15         whenIsJust,
16         expectJust,
17
18         MaybeT(..)
19     ) where
20 import Control.Applicative
21 import Control.Monad
22 import Data.Maybe
23
24 infixr 4 `orElse`
25 \end{code}
26
27 %************************************************************************
28 %*                                                                      *
29 \subsection[Maybe type]{The @Maybe@ type}
30 %*                                                                      *
31 %************************************************************************
32
33 \begin{code}
34 firstJust :: Maybe a -> Maybe a -> Maybe a
35 firstJust a b = firstJusts [a, b]
36
37 -- | Takes a list of @Maybes@ and returns the first @Just@ if there is one, or
38 -- @Nothing@ otherwise.
39 firstJusts :: [Maybe a] -> Maybe a
40 firstJusts = msum
41
42 expectJust :: String -> Maybe a -> a
43 {-# INLINE expectJust #-}
44 expectJust _   (Just x) = x
45 expectJust err Nothing  = error ("expectJust " ++ err)
46
47 whenIsJust :: Monad m => Maybe a -> (a -> m ()) -> m ()
48 whenIsJust (Just x) f = f x
49 whenIsJust Nothing  _ = return ()
50
51 -- | Flipped version of @fromMaybe@, useful for chaining.
52 orElse :: Maybe a -> a -> a
53 orElse = flip fromMaybe
54 \end{code}
55
56 %************************************************************************
57 %*                                                                      *
58 \subsection[MaybeT type]{The @MaybeT@ monad transformer}
59 %*                                                                      *
60 %************************************************************************
61
62 \begin{code}
63
64 newtype MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)}
65
66 instance Functor m => Functor (MaybeT m) where
67   fmap f x = MaybeT $ fmap (fmap f) $ runMaybeT x
68
69 instance (Monad m, Functor m) => Applicative (MaybeT m) where
70   pure  = return
71   (<*>) = ap
72
73 instance Monad m => Monad (MaybeT m) where
74   return = MaybeT . return . Just
75   x >>= f = MaybeT $ runMaybeT x >>= maybe (return Nothing) (runMaybeT . f)
76   fail _ = MaybeT $ return Nothing
77
78 \end{code}
79
80
81 %************************************************************************
82 %*                                                                      *
83 \subsection[MaybeErr type]{The @MaybeErr@ type}
84 %*                                                                      *
85 %************************************************************************
86
87 \begin{code}
88 data MaybeErr err val = Succeeded val | Failed err
89
90 instance Functor (MaybeErr err) where
91   fmap = liftM
92
93 instance Applicative (MaybeErr err) where
94   pure  = return
95   (<*>) = ap
96
97 instance Monad (MaybeErr err) where
98   return v = Succeeded v
99   Succeeded v >>= k = k v
100   Failed e    >>= _ = Failed e
101
102 isSuccess :: MaybeErr err val -> Bool
103 isSuccess (Succeeded {}) = True
104 isSuccess (Failed {})    = False
105
106 failME :: err -> MaybeErr err val
107 failME e = Failed e
108 \end{code}