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