# Haskell/Hierarchical libraries/Maybe

The **Maybe** data type is a means of being explicit that you are not sure that a function will be successful when it is executed.

## Motivation[edit]

Many languages require you to guess what they will do when a calculation did not finish properly. For example, an array lookup signature may look like this in pseudocode:

getPosition(Array a, Value v) returns Integer

But what happens if it *doesn't* find the item? It could return a `null`

value, or the integer '-1' which would also be an obvious sign that something went wrong. But there's no way of knowing what will happen without examining the code for this procedure to see what the programmer chose to do. In a library without available code this might not even be possible.

The alternative is to explicitly state what the function *should* return (in this case, Integer), but also that it might not work as intended — Maybe Integer. This is the intention of the Maybe datatype. So in Haskell, we could write the above signature as:

getPosition :: Array -> Value -> Maybe Integer

If the function is successful you want to return the result; otherwise, you want to return an explicit failure. This could be simulated as a tuple of type `(Bool, `

where *a*)*a* is the "actual" return type of the function. But what would you put in the *a* slot if it failed? There's no obvious answer. Besides which, the Maybe type is easier to use and has a selection of library functions for dealing with values which may fail to return an explicit answer.

## Definition[edit]

The Standard Prelude defines the Maybe type as follows, and more utility functions exist in the Data.Maybe library.

data Maybe a = Nothing | Just a

The type *a* is polymorphic and can contain complex types or even other monads (such as IO () types).

## Library functions[edit]

The module `Data.Maybe`

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

### Querying[edit]

There are two obvious functions to give you information about a Maybe value.

`isJust`

[edit]

This returns True if the argument is in the form `Just _`

.

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

`isNothing`

[edit]

The dual of `isJust`

: returns True if its argument is `Nothing`

.

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

### Getting out[edit]

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

`maybe`

[edit]

`maybe`

is a function that takes a default value to use if its argument is `Nothing`

, a function to apply if its argument is in the form `Just _`

, and a Maybe value.

maybe :: b -> (a -> b) -> Maybe a -> b maybe _ f (Just x) = f x maybe z _ Nothing = z

`fromMaybe`

[edit]

A frequent pattern is to use the `maybe`

function, but not want to change the value if it was a `Just`

. That is, call `maybe`

with the second parameter being `id`

. This is precisely `fromMaybe`

.

fromMaybe :: a -> Maybe a -> a fromMaybe z = maybe z id

`fromJust`

[edit]

There are certain occasions when you *know* a function that ends in a Maybe value will produce a `Just`

. In these cases, you can use the `fromJust`

function, which just strips off a `Just`

constructor.

fromJust :: Maybe a -> a fromJust (Just x) = x fromJust Nothing = error "fromJust: Nothing"

### Lists and Maybe[edit]

Lists are, in some ways, similar to the Maybe datatype (indeed, this relationship will be further explored when you learn about monads). As such, there are a couple of functions for converting between one and the other.

`listToMaybe`

[edit]

This function, and the following one, makes a lot of sense when you think about Maybe and list values in terms of computations (which will be more fully explained in the section on Advanced monads).

With lists, `[]`

represents a failed computation. With Maybe, `Nothing`

does. `listToMaybe`

converts between the list and Maybe monad. When the parameter (in the list monad) indicated a successful computation, only the first solution is taken to place in the Maybe value.

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

`maybeToList`

[edit]

The obvious opposite of `listToMaybe`

.

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

### Lists manipulation[edit]

Finally, there are a couple of functions which are analogues of the normal Prelude list manipulation functions, but specialised to Maybe values.

#### Continue on some failures (like 'or')[edit]

`catMaybes`

[edit]

Given a list of Maybe values, `catMaybes`

extracts all the values in the form `Just _`

, and strips off the `Just`

constructors. This is easily defined with a list comprehension, 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)

But the actual definition may be more efficient and traverse the list once:

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]

`sequence`

[edit]

Sometimes you want to collect the values if and only if all succeeded:

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