The Maybe
data is used with functions that might be unsuccessful. The full description is in Maybe monad chapter.
Definition
editThe Standard Prelude defines the Maybe
type as follows:
data Maybe a = Nothing | Just a
Recall that the type a is polymorphic and can contain complex types or even other monads (such as IO () types).
Library functions
editThe module Data.Maybe
, in the standard hierarchical libraries, contains a wealth of functions for working with Maybe values.
Querying
editTwo obvious functions give you information about a Maybe value:
isJust
edit
isJust
returns True if when given an argument in the form Just _
.
isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust Nothing = False
isNothing
edit
isNothing
returns True if its argument is Nothing
.
isNothing :: Maybe a -> Bool
isNothing (Just _) = False
isNothing Nothing = True
Getting out
editThere are a handful of functions for converting Maybe values to non-Maybe values.
maybe
edit
maybe
applies a given function to the internal value passed by a Just
but otherwise returns a default value when given Nothing
.
maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing = z
fromMaybe
edit
We might want to use maybe
without applying any function to the Just
. We can do that by calling maybe
with the function id
. Data.Maybe
already has this as fromMaybe
:
fromMaybe :: a -> Maybe a -> a
fromMaybe z = maybe z id
Note the use of point-free style. maybe z id
evaluates to a function that is ready to take a Maybe
value.
Lists and Maybe
editThe many similarities between lists and Maybe
are discussed in the List monad chapter. Given the connections, there are a couple of functions for converting between one and the other:
listToMaybe
edit
Failed computations return []
for lists and Nothing
for Maybe. listToMaybe
converts from the list to the Maybe monad. As Maybe
can only hold one value, listToMaybe
only takes the first solution from a list.
listToMaybe :: [a] -> Maybe a
listToMaybe [] = Nothing
listToMaybe (x:_) = Just x
maybeToList
edit
The reverse listToMaybe
is, of course, maybeToList
:
maybeToList :: Maybe a -> [a]
maybeToList Nothing = []
maybeToList (Just x) = [x]
Lists manipulation
editThere are a couple of functions which are analogues of the normal Prelude list manipulation functions but are specialized to Maybe values.
Continue on some failures
editWe might want an OR function that won't make a whole computation fail just because one part failed.
catMaybes
edit
Given a list of Maybe values, catMaybes
extracts all the values in the form Just _
, and strips off the Just
constructors. List comprehension does the job here (as we showed in the pattern matching chapter):
catMaybes :: [Maybe a] -> [a]
catMaybes ms = [ x | Just x <- ms ]
mapMaybe
edit
mapMaybe
applies a function to a list and collects the successes. It can be understood as a composition of functions you already know:
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
mapMaybe f xs = catMaybes (map f xs)
However, the actual definition in Data.Maybe
traverses the list is potentially more efficient:
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
mapMaybe _ [] = []
mapMaybe f (x:xs) =
case f x of
Just y -> y : mapMaybe f xs
Nothing -> mapMaybe f xs
Stop on failure
editRather than OR, we might want to collect values if and only if all succeed.
sequence
edit
sequence :: [Maybe a] -> Maybe [a]
sequence [] = Just []
sequence (Nothing:xs) = Nothing
sequence (Just x:xs) = case sequence xs of
Just xs' -> Just (x:xs')
_ -> Nothing