2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[Maybes]{The `Maybe' types and associated utility functions}
7 #include "HsVersions.h"
10 -- Maybe(..), -- no, it's in 1.3
20 mkLookupFun, mkLookupFunDef,
31 CHK_Ubiq() -- debugging consistency check
32 import Unique (Unique) -- only for specialising
34 #if __GLASGOW_HASKELL__ >= 204
35 import Maybe( catMaybes, mapMaybe )
41 %************************************************************************
43 \subsection[Maybe type]{The @Maybe@ type}
45 %************************************************************************
48 maybeToBool :: Maybe a -> Bool
49 maybeToBool Nothing = False
50 maybeToBool (Just x) = True
53 @catMaybes@ takes a list of @Maybe@s and returns a list of
54 the contents of all the @Just@s in it. @allMaybes@ collects
55 a list of @Justs@ into a single @Just@, returning @Nothing@ if there
59 allMaybes :: [Maybe a] -> Maybe [a]
60 allMaybes [] = Just []
61 allMaybes (Nothing : ms) = Nothing
62 allMaybes (Just x : ms) = case (allMaybes ms) of
64 Just xs -> Just (x:xs)
66 #if __GLASGOW_HASKELL__ < 204
67 -- After 2.04 we get these from the library Maybe
68 catMaybes :: [Maybe a] -> [a]
70 catMaybes (Nothing : xs) = catMaybes xs
71 catMaybes (Just x : xs) = (x : catMaybes xs)
73 mapMaybe :: (a -> Maybe b) -> [a] -> [b]
75 mapMaybe f (x:xs) = case f x of
76 Just y -> y : mapMaybe f xs
77 Nothing -> mapMaybe f xs
81 @firstJust@ takes a list of @Maybes@ and returns the
82 first @Just@ if there is one, or @Nothing@ otherwise.
85 firstJust :: [Maybe a] -> Maybe a
86 firstJust [] = Nothing
87 firstJust (Just x : ms) = Just x
88 firstJust (Nothing : ms) = firstJust ms
92 findJust :: (a -> Maybe b) -> [a] -> Maybe b
93 findJust f [] = Nothing
94 findJust f (a:as) = case f a of
95 Nothing -> findJust f as
100 expectJust :: String -> Maybe a -> a
101 {-# INLINE expectJust #-}
102 expectJust err (Just x) = x
103 expectJust err Nothing = error ("expectJust " ++ err)
109 seqMaybe :: Maybe a -> Maybe a -> Maybe a
110 seqMaybe (Just x) _ = Just x
111 seqMaybe Nothing my = my
113 returnMaybe :: a -> Maybe a
123 @assocMaybe@ looks up in an assocation list, returning
124 @Nothing@ if it fails.
127 assocMaybe :: (Eq a) => [(a,b)] -> a -> Maybe b
133 lookup ((tv,ty):rest) = if key == tv then Just ty else lookup rest
135 {-# SPECIALIZE assocMaybe
136 :: [(FAST_STRING, b)] -> FAST_STRING -> Maybe b
137 , [(Int, b)] -> Int -> Maybe b
138 , [(Unique, b)] -> Unique -> Maybe b
142 @mkLookupFun eq alist@ is a function which looks up
143 its argument in the association list @alist@, returning a Maybe type.
144 @mkLookupFunDef@ is similar except that it is given a value to return
148 mkLookupFun :: (key -> key -> Bool) -- Equality predicate
149 -> [(key,val)] -- The assoc list
151 -> Maybe val -- The corresponding value
153 mkLookupFun eq alist s
154 = case [a | (s',a) <- alist, s' `eq` s] of
158 mkLookupFunDef :: (key -> key -> Bool) -- Equality predicate
159 -> [(key,val)] -- The assoc list
160 -> val -- Value to return on failure
162 -> val -- The corresponding value
164 mkLookupFunDef eq alist deflt s
165 = case [a | (s',a) <- alist, s' `eq` s] of
170 %************************************************************************
172 \subsection[MaybeErr type]{The @MaybeErr@ type}
174 %************************************************************************
177 data MaybeErr val err = Succeeded val | Failed err
181 thenMaB :: MaybeErr val1 err -> (val1 -> MaybeErr val2 err) -> MaybeErr val2 err
187 returnMaB :: val -> MaybeErr val err
188 returnMaB v = Succeeded v
190 failMaB :: err -> MaybeErr val err