\section[Maybes]{The `Maybe' types and associated utility functions}
\begin{code}
-#if defined(COMPILING_GHC)
#include "HsVersions.h"
-#endif
module Maybes (
-- Maybe(..), -- no, it's in 1.3
MaybeErr(..),
+ mapMaybe,
allMaybes,
- catMaybes,
firstJust,
expectJust,
maybeToBool,
failMaB,
failMaybe,
seqMaybe,
- mapMaybe,
returnMaB,
returnMaybe,
thenMaB,
- thenMaybe
-
-#if ! defined(COMPILING_GHC)
- , findJust
- , foldlMaybeErrs
- , listMaybeErrs
-#endif
+ catMaybes
) where
-#if defined(COMPILING_GHC)
-
-CHK_Ubiq() -- debugging consistency check
+CHK_Ubiq() -- debugging consistency check
+import Unique (Unique) -- only for specialising
+#if __GLASGOW_HASKELL__ >= 204
+import Maybe( catMaybes, mapMaybe )
#endif
+
\end{code}
%************************************************************************
\begin{code}
-#if __HASKELL1__ < 3
-data Maybe a
- = Nothing
- | Just a
-#endif
-\end{code}
-
-\begin{code}
maybeToBool :: Maybe a -> Bool
maybeToBool Nothing = False
maybeToBool (Just x) = True
are any @Nothings@.
\begin{code}
-catMaybes :: [Maybe a] -> [a]
-catMaybes [] = []
-catMaybes (Nothing : xs) = catMaybes xs
-catMaybes (Just x : xs) = (x : catMaybes xs)
-
allMaybes :: [Maybe a] -> Maybe [a]
allMaybes [] = Just []
allMaybes (Nothing : ms) = Nothing
allMaybes (Just x : ms) = case (allMaybes ms) of
Nothing -> Nothing
Just xs -> Just (x:xs)
+
+#if __GLASGOW_HASKELL__ < 204
+ -- After 2.04 we get these from the library Maybe
+catMaybes :: [Maybe a] -> [a]
+catMaybes [] = []
+catMaybes (Nothing : xs) = catMaybes xs
+catMaybes (Just x : xs) = (x : catMaybes xs)
+
+mapMaybe :: (a -> Maybe b) -> [a] -> [b]
+mapMaybe f [] = []
+mapMaybe f (x:xs) = case f x of
+ Just y -> y : mapMaybe f xs
+ Nothing -> mapMaybe f xs
+#endif
\end{code}
@firstJust@ takes a list of @Maybes@ and returns the
The Maybe monad
~~~~~~~~~~~~~~~
\begin{code}
-#if __HASKELL1__ < 3
-thenMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
-m `thenMaybe` k = case m of
- Nothing -> Nothing
- Just a -> k a
-#endif
-
seqMaybe :: Maybe a -> Maybe a -> Maybe a
seqMaybe (Just x) _ = Just x
seqMaybe Nothing my = my
failMaybe :: Maybe a
failMaybe = Nothing
-
-mapMaybe :: (a -> Maybe b) -> [a] -> Maybe [b]
-mapMaybe f [] = returnMaybe []
-mapMaybe f (x:xs) = f x `thenMaybe` \ x' ->
- mapMaybe f xs `thenMaybe` \ xs' ->
- returnMaybe (x':xs')
\end{code}
Lookup functions
lookup [] = Nothing
lookup ((tv,ty):rest) = if key == tv then Just ty else lookup rest
-#if defined(COMPILING_GHC)
-{-? SPECIALIZE assocMaybe
- :: [(String, b)] -> String -> Maybe b,
- [(Id, b)] -> Id -> Maybe b,
- [(Class, b)] -> Class -> Maybe b,
- [(Int, b)] -> Int -> Maybe b,
- [(Name, b)] -> Name -> Maybe b,
- [(TyVar, b)] -> TyVar -> Maybe b,
- [(TyVarTemplate, b)] -> TyVarTemplate -> Maybe b
+{-# SPECIALIZE assocMaybe
+ :: [(FAST_STRING, b)] -> FAST_STRING -> Maybe b
+ , [(Int, b)] -> Int -> Maybe b
+ , [(Unique, b)] -> Unique -> Maybe b
#-}
-#endif
\end{code}
@mkLookupFun eq alist@ is a function which looks up
failMaB :: err -> MaybeErr val err
failMaB e = Failed e
\end{code}
-
-
-@listMaybeErrs@ takes a list of @MaybeErrs@ and, if they all succeed, returns
-a @Succeeded@ of a list of their values. If any fail, it returns a
-@Failed@ of the list of all the errors in the list.
-
-\begin{code}
-listMaybeErrs :: [MaybeErr val err] -> MaybeErr [val] [err]
-listMaybeErrs
- = foldr combine (Succeeded [])
- where
- combine (Succeeded v) (Succeeded vs) = Succeeded (v:vs)
- combine (Failed err) (Succeeded _) = Failed [err]
- combine (Succeeded v) (Failed errs) = Failed errs
- combine (Failed err) (Failed errs) = Failed (err:errs)
-\end{code}
-
-@foldlMaybeErrs@ works along a list, carrying an accumulator; it
-applies the given function to the accumulator and the next list item,
-accumulating any errors that occur.
-
-\begin{code}
-foldlMaybeErrs :: (acc -> input -> MaybeErr acc err)
- -> acc
- -> [input]
- -> MaybeErr acc [err]
-
-foldlMaybeErrs k accum ins = do_it [] accum ins
- where
- do_it [] acc [] = Succeeded acc
- do_it errs acc [] = Failed errs
- do_it errs acc (v:vs) = case (k acc v) of
- Succeeded acc' -> do_it errs acc' vs
- Failed err -> do_it (err:errs) acc vs
-\end{code}