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