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