3cf3221ee6411727e5199f496c183ee440f84e0c
[ghc-hetmet.git] / ghc / compiler / utils / Maybes.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[Maybes]{The `Maybe' types and associated utility functions}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module Maybes (
10 --      Maybe(..), -- no, it's in 1.3
11         MaybeErr(..),
12
13         mapMaybe,
14         allMaybes,
15         firstJust,
16         expectJust,
17         maybeToBool,
18
19         assocMaybe,
20         mkLookupFun, mkLookupFunDef,
21
22         failMaB,
23         failMaybe,
24         seqMaybe,
25         returnMaB,
26         returnMaybe,
27         thenMaB,
28         catMaybes
29     ) where
30
31 #if __GLASGOW_HASKELL__ >= 204
32 import Maybe( catMaybes, mapMaybe )
33 #endif
34
35 \end{code}
36
37
38 %************************************************************************
39 %*                                                                      *
40 \subsection[Maybe type]{The @Maybe@ type}
41 %*                                                                      *
42 %************************************************************************
43
44 \begin{code}
45 maybeToBool :: Maybe a -> Bool
46 maybeToBool Nothing  = False
47 maybeToBool (Just x) = True
48 \end{code}
49
50 @catMaybes@ takes a list of @Maybe@s and returns a list of
51 the contents of all the @Just@s in it.  @allMaybes@ collects
52 a list of @Justs@ into a single @Just@, returning @Nothing@ if there
53 are any @Nothings@.
54
55 \begin{code}
56 allMaybes :: [Maybe a] -> Maybe [a]
57 allMaybes [] = Just []
58 allMaybes (Nothing : ms) = Nothing
59 allMaybes (Just x  : ms) = case (allMaybes ms) of
60                              Nothing -> Nothing
61                              Just xs -> Just (x:xs)
62
63 #if __GLASGOW_HASKELL__ < 204
64         -- After 2.04 we get these from the library Maybe
65 catMaybes :: [Maybe a] -> [a]
66 catMaybes []                = []
67 catMaybes (Nothing : xs)   = catMaybes xs
68 catMaybes (Just x : xs)    = (x : catMaybes xs)
69
70 mapMaybe :: (a -> Maybe b) -> [a] -> [b]
71 mapMaybe f [] = []
72 mapMaybe f (x:xs) = case f x of
73                         Just y  -> y : mapMaybe f xs
74                         Nothing -> mapMaybe f xs
75 #endif
76 \end{code}
77
78 @firstJust@ takes a list of @Maybes@ and returns the
79 first @Just@ if there is one, or @Nothing@ otherwise.
80
81 \begin{code}
82 firstJust :: [Maybe a] -> Maybe a
83 firstJust [] = Nothing
84 firstJust (Just x  : ms) = Just x
85 firstJust (Nothing : ms) = firstJust ms
86 \end{code}
87
88 \begin{code}
89 findJust :: (a -> Maybe b) -> [a] -> Maybe b
90 findJust f []     = Nothing
91 findJust f (a:as) = case f a of
92                       Nothing -> findJust f as
93                       b  -> b
94 \end{code}
95
96 \begin{code}
97 expectJust :: String -> Maybe a -> a
98 {-# INLINE expectJust #-}
99 expectJust err (Just x) = x
100 expectJust err Nothing  = error ("expectJust " ++ err)
101 \end{code}
102
103 The Maybe monad
104 ~~~~~~~~~~~~~~~
105 \begin{code}
106 seqMaybe :: Maybe a -> Maybe a -> Maybe a
107 seqMaybe (Just x) _  = Just x
108 seqMaybe Nothing  my = my
109
110 returnMaybe :: a -> Maybe a
111 returnMaybe = Just
112
113 failMaybe :: Maybe a
114 failMaybe = Nothing
115 \end{code}
116
117 Lookup functions
118 ~~~~~~~~~~~~~~~~
119
120 @assocMaybe@ looks up in an assocation list, returning
121 @Nothing@ if it fails.
122
123 \begin{code}
124 assocMaybe :: (Eq a) => [(a,b)] -> a -> Maybe b
125
126 assocMaybe alist key
127   = lookup alist
128   where
129     lookup []             = Nothing
130     lookup ((tv,ty):rest) = if key == tv then Just ty else lookup rest
131 \end{code}
132
133 @mkLookupFun eq alist@ is a function which looks up
134 its argument in the association list @alist@, returning a Maybe type.
135 @mkLookupFunDef@ is similar except that it is given a value to return
136 on failure.
137
138 \begin{code}
139 mkLookupFun :: (key -> key -> Bool)     -- Equality predicate
140             -> [(key,val)]              -- The assoc list
141             -> key                      -- The key
142             -> Maybe val                -- The corresponding value
143
144 mkLookupFun eq alist s
145   = case [a | (s',a) <- alist, s' `eq` s] of
146       []    -> Nothing
147       (a:_) -> Just a
148
149 mkLookupFunDef :: (key -> key -> Bool)  -- Equality predicate
150                -> [(key,val)]           -- The assoc list
151                -> val                   -- Value to return on failure
152                -> key                   -- The key
153                -> val                   -- The corresponding value
154
155 mkLookupFunDef eq alist deflt s
156   = case [a | (s',a) <- alist, s' `eq` s] of
157       []    -> deflt
158       (a:_) -> a
159 \end{code}
160
161 %************************************************************************
162 %*                                                                      *
163 \subsection[MaybeErr type]{The @MaybeErr@ type}
164 %*                                                                      *
165 %************************************************************************
166
167 \begin{code}
168 data MaybeErr val err = Succeeded val | Failed err
169 \end{code}
170
171 \begin{code}
172 thenMaB :: MaybeErr val1 err -> (val1 -> MaybeErr val2 err) -> MaybeErr val2 err
173 thenMaB m k
174   = case m of
175       Succeeded v -> k v
176       Failed e    -> Failed e
177
178 returnMaB :: val -> MaybeErr val err
179 returnMaB v = Succeeded v
180
181 failMaB :: err -> MaybeErr val err
182 failMaB e = Failed e
183 \end{code}