Add {-# OPTIONS_GHC -w #-} and some blurb to all compiler modules
[ghc-hetmet.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 {-# OPTIONS_GHC -w #-}
8 -- The above warning supression flag is a temporary kludge.
9 -- While working on this module you are encouraged to remove it and fix
10 -- any warnings in the module. See
11 --     http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings
12 -- for details
13
14 module Maybes (
15         module Data.Maybe,      -- Re-export all of Maybe
16
17         MaybeErr(..),   -- Instance of Monad
18         failME, isSuccess,
19
20         orElse, 
21         mapCatMaybes,
22         allMaybes,
23         firstJust,
24         expectJust,
25         maybeToBool,
26
27         thenMaybe, seqMaybe, returnMaybe, failMaybe, fmapMMaybe
28     ) where
29
30 #include "HsVersions.h"
31
32 import Data.Maybe
33
34 infixr 4 `orElse`
35 \end{code}
36
37 %************************************************************************
38 %*                                                                      *
39 \subsection[Maybe type]{The @Maybe@ type}
40 %*                                                                      *
41 %************************************************************************
42
43 \begin{code}
44 maybeToBool :: Maybe a -> Bool
45 maybeToBool Nothing  = False
46 maybeToBool (Just x) = True
47 \end{code}
48
49 @catMaybes@ takes a list of @Maybe@s and returns a list of
50 the contents of all the @Just@s in it.  @allMaybes@ collects
51 a list of @Justs@ into a single @Just@, returning @Nothing@ if there
52 are any @Nothings@.
53
54 \begin{code}
55 allMaybes :: [Maybe a] -> Maybe [a]
56 allMaybes [] = Just []
57 allMaybes (Nothing : ms) = Nothing
58 allMaybes (Just x  : ms) = case (allMaybes ms) of
59                              Nothing -> Nothing
60                              Just xs -> Just (x:xs)
61
62 \end{code}
63
64 @firstJust@ takes a list of @Maybes@ and returns the
65 first @Just@ if there is one, or @Nothing@ otherwise.
66
67 \begin{code}
68 firstJust :: [Maybe a] -> Maybe a
69 firstJust [] = Nothing
70 firstJust (Just x  : ms) = Just x
71 firstJust (Nothing : ms) = firstJust ms
72 \end{code}
73
74 \begin{code}
75 expectJust :: String -> Maybe a -> a
76 {-# INLINE expectJust #-}
77 expectJust err (Just x) = x
78 expectJust err Nothing  = error ("expectJust " ++ err)
79 \end{code}
80
81 \begin{code}
82 mapCatMaybes :: (a -> Maybe b) -> [a] -> [b]
83 mapCatMaybes f [] = []
84 mapCatMaybes f (x:xs) = case f x of
85                           Just y  -> y : mapCatMaybes f xs
86                           Nothing -> mapCatMaybes f xs
87 \end{code}
88
89 The Maybe monad
90 ~~~~~~~~~~~~~~~
91 \begin{code}
92 seqMaybe :: Maybe a -> Maybe a -> Maybe a
93 seqMaybe (Just x) _  = Just x
94 seqMaybe Nothing  my = my
95
96 thenMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
97 thenMaybe ma mb = case ma of
98                     Just x  -> mb x
99                     Nothing -> Nothing
100
101 returnMaybe :: a -> Maybe a
102 returnMaybe = Just
103
104 failMaybe :: Maybe a
105 failMaybe = Nothing
106
107 orElse :: Maybe a -> a -> a
108 (Just x) `orElse` y = x
109 Nothing  `orElse` y = y
110
111 fmapMMaybe :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
112 fmapMMaybe f Nothing  = return Nothing
113 fmapMMaybe f (Just x) = f x >>= \x' -> return (Just x')
114
115 \end{code}
116
117
118 %************************************************************************
119 %*                                                                      *
120 \subsection[MaybeErr type]{The @MaybeErr@ type}
121 %*                                                                      *
122 %************************************************************************
123
124 \begin{code}
125 data MaybeErr err val = Succeeded val | Failed err
126
127 instance Monad (MaybeErr err) where
128   return v = Succeeded v
129   Succeeded v >>= k = k v
130   Failed e    >>= k = Failed e
131
132 isSuccess :: MaybeErr err val -> Bool
133 isSuccess (Succeeded {}) = True
134 isSuccess (Failed {})    = False
135
136 failME :: err -> MaybeErr err val
137 failME e = Failed e
138 \end{code}