# 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
```