Maybe (Solutions) Libraries Reference edit this chapter

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

## Definition

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

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

### Querying

Two obvious functions give you information about a Maybe value:

### `isJust`

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

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

### `isNothing`

`isNothing` returns True if its argument is `Nothing`.

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

### Getting out

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

#### `maybe`

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

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

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`

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`

The reverse `listToMaybe` is, of course, `maybeToList`:

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

### Lists manipulation

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

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

##### `catMaybes`

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`

`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

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

##### `sequence`
```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
```
 Maybe Solutions to exercises Libraries Reference edit this chapter Haskell edit book structure