Haskell/Libraries/Maybe

The Maybe data is used with functions that might be unsuccessful. The full description is in Maybe monad chapter.

DefinitionEdit

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 functionsEdit

The module Data.Maybe, in the standard hierarchical libraries, contains a wealth of functions for working with Maybe values.

QueryingEdit

Two obvious functions give you information about a Maybe value:

isJustEdit

isJust returns True if when given an argument in the form Just _.

isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust Nothing  = False

isNothingEdit

isNothing returns True if its argument is Nothing.

isNothing :: Maybe a -> Bool
isNothing (Just _) = False
isNothing Nothing  = True

Getting outEdit

There are a handful of functions for converting Maybe values to non-Maybe values.

maybeEdit

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

fromMaybeEdit

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 MaybeEdit

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:

listToMaybeEdit

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

maybeToListEdit

The reverse listToMaybe is, of course, maybeToList:

maybeToList :: Maybe a -> [a]
maybeToList Nothing  = []
maybeToList (Just x) = [x]

Lists manipulationEdit

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 failuresEdit

We might want an OR function that won't make a whole computation fail just because one part failed.

catMaybesEdit

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 ]
mapMaybeEdit

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 failureEdit

Rather than OR, we might want to collect values if and only if all succeed.

sequenceEdit
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