Haskell/Libraries/Maybe
The Maybe data is used with functions that might be unsuccessful. The full description is in Maybe monad chapter.
Definition
[edit | edit source]The 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
[edit | edit source]The module Data.Maybe, in the standard hierarchical libraries, contains a wealth of functions for working with Maybe values.
Querying
[edit | edit source]Two obvious functions give you information about a Maybe value:
isJust
[edit | edit source]isJust returns True if when given an argument in the form Just _.
isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust Nothing = False
isNothing
[edit | edit source]isNothing returns True if its argument is Nothing.
isNothing :: Maybe a -> Bool
isNothing (Just _) = False
isNothing Nothing = True
Getting out
[edit | edit source]There are a handful of functions for converting Maybe values to non-Maybe values.
maybe
[edit | edit source]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 | edit source]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
[edit | edit source]The 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 | edit source]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 | edit source]The reverse listToMaybe is, of course, maybeToList:
maybeToList :: Maybe a -> [a]
maybeToList Nothing = []
maybeToList (Just x) = [x]
Lists manipulation
[edit | edit source]There 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
[edit | edit source]We might want an OR function that won't make a whole computation fail just because one part failed.
catMaybes
[edit | edit source]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 | edit source]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
[edit | edit source]Rather than OR, we might want to collect values if and only if all succeed.
sequence
[edit | edit source]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