[project @ 2000-10-24 08:40:09 by simonpj]
[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         Maybe2(..), Maybe3(..),
9         MaybeErr(..),
10
11         orElse, 
12         mapMaybe,
13         allMaybes,
14         firstJust,
15         expectJust,
16         maybeToBool,
17
18         thenMaybe, seqMaybe, returnMaybe, failMaybe, catMaybes,
19
20         thenMaB, returnMaB, failMaB
21
22     ) where
23
24 #include "HsVersions.h"
25
26 import Maybe( catMaybes, mapMaybe )
27
28
29 infixr 4 `orElse`
30 \end{code}
31
32
33 %************************************************************************
34 %*                                                                      *
35 \subsection[Maybe2,3 types]{The @Maybe2@ and @Maybe3@ types}
36 %*                                                                      *
37 %************************************************************************
38
39 \begin{code}
40 data Maybe2 a b   = Just2 a b   | Nothing2  deriving (Eq,Show)
41 data Maybe3 a b c = Just3 a b c | Nothing3  deriving (Eq,Show)
42 \end{code}
43
44
45 %************************************************************************
46 %*                                                                      *
47 \subsection[Maybe type]{The @Maybe@ type}
48 %*                                                                      *
49 %************************************************************************
50
51 \begin{code}
52 maybeToBool :: Maybe a -> Bool
53 maybeToBool Nothing  = False
54 maybeToBool (Just x) = True
55 \end{code}
56
57 @catMaybes@ takes a list of @Maybe@s and returns a list of
58 the contents of all the @Just@s in it.  @allMaybes@ collects
59 a list of @Justs@ into a single @Just@, returning @Nothing@ if there
60 are any @Nothings@.
61
62 \begin{code}
63 allMaybes :: [Maybe a] -> Maybe [a]
64 allMaybes [] = Just []
65 allMaybes (Nothing : ms) = Nothing
66 allMaybes (Just x  : ms) = case (allMaybes ms) of
67                              Nothing -> Nothing
68                              Just xs -> Just (x:xs)
69
70 \end{code}
71
72 @firstJust@ takes a list of @Maybes@ and returns the
73 first @Just@ if there is one, or @Nothing@ otherwise.
74
75 \begin{code}
76 firstJust :: [Maybe a] -> Maybe a
77 firstJust [] = Nothing
78 firstJust (Just x  : ms) = Just x
79 firstJust (Nothing : ms) = firstJust ms
80 \end{code}
81
82 \begin{code}
83 findJust :: (a -> Maybe b) -> [a] -> Maybe b
84 findJust f []     = Nothing
85 findJust f (a:as) = case f a of
86                       Nothing -> findJust f as
87                       b  -> b
88 \end{code}
89
90 \begin{code}
91 expectJust :: String -> Maybe a -> a
92 {-# INLINE expectJust #-}
93 expectJust err (Just x) = x
94 expectJust err Nothing  = error ("expectJust " ++ err)
95 \end{code}
96
97 The Maybe monad
98 ~~~~~~~~~~~~~~~
99 \begin{code}
100 seqMaybe :: Maybe a -> Maybe a -> Maybe a
101 seqMaybe (Just x) _  = Just x
102 seqMaybe Nothing  my = my
103
104 thenMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
105 thenMaybe ma mb = case ma of
106                     Just x  -> mb x
107                     Nothing -> Nothing
108
109 returnMaybe :: a -> Maybe a
110 returnMaybe = Just
111
112 failMaybe :: Maybe a
113 failMaybe = Nothing
114
115 orElse :: Maybe a -> a -> a
116 (Just x) `orElse` y = x
117 Nothing  `orElse` y = y
118 \end{code}
119
120
121 %************************************************************************
122 %*                                                                      *
123 \subsection[MaybeErr type]{The @MaybeErr@ type}
124 %*                                                                      *
125 %************************************************************************
126
127 \begin{code}
128 data MaybeErr val err = Succeeded val | Failed err
129 \end{code}
130
131 \begin{code}
132 thenMaB :: MaybeErr val1 err -> (val1 -> MaybeErr val2 err) -> MaybeErr val2 err
133 thenMaB m k
134   = case m of
135       Succeeded v -> k v
136       Failed e    -> Failed e
137
138 returnMaB :: val -> MaybeErr val err
139 returnMaB v = Succeeded v
140
141 failMaB :: err -> MaybeErr val err
142 failMaB e = Failed e
143 \end{code}
144