## 3.10. Monadic Operations

When you work with generic types, and with functions that yield values from these types, it is useful to supply methods that let you *compose* these functions—that is, carry out one after another. In this section, you will see a design pattern for providing such compositions.

Consider a generic type `G<T>` with one type parameter, such as `List<T>` (zero or more values of type `T`), `Optional<T>` (zero or one values of type `T`), or `Future<T>` (a value of type `T` that will be available in the future).

Also consider a function `T -> U`, or a `Function<T, U>` object.

It often makes sense to apply this function to a `G<T>` (that is, a `List<T>`, `Optional<T>`, `Future<T>`, and so on). How this works exactly depends on the nature of the generic type `G`. For example, applying a function *f* to a `List` with elements *e*_{1},..., *e _{n}* means creating a list with elements

*f*(

*e*

_{1}),...,

*f*(

*e*).

_{n}Applying *f* to an `Optional<T>` containing *v* means creating an `Optional<U>` containing *f*(*v*). But if *f* is applied to an empty `Optional<T>` without a value, the result is an empty `Optional<U>`.

Applying *f* to a `Future<T>` simply means to apply it whenever it is available. The result is a `Future<U>`.

By tradition, this operation is usually called `map`. There is a `map` method for `Stream` and `Optional`. The `CompletableFuture` class that we will discuss in Chapter 6 has an operation that does just what `map` should do, but it is called `thenApply`. There is no `map` for a plain `Future<V>`, but it is not hard to supply one (see Exercise 21).

So far, that is a fairly straightforward idea. It gets more complex when you look at functions `T -> G<U>` instead of functions `T -> U`. For example, consider getting the web page for a URL. Since it takes some time to fetch the page, that is a function `URL -> Future<String>`. Now suppose you have a `Future<URL>`, a URL that will arrive sometime. Clearly it makes sense to map the function to that `Future`. Wait for the URL to arrive, then feed it to the function and wait for the string to arrive. This operation has traditionally been called `flatMap`.

The name `flatMap` comes from sets. Suppose you have a “many-valued” function—a function computing a set of possible answers. And then you have another such function. How can you compose these functions? If *f*(*x*) is the set {*y*_{1},..., *y _{n}*}, you apply

*g*to each element, yielding {

*g*(

*y*

_{1}),...,

*g*(

*y*}. But each of the

_{n})*g*(

*y*) is a

_{i}*set*. You want to “flatten” the set of sets so that you get the set of all possible values of both functions.

There is a `flatMap` for `Optional<T>` as well. Given a function `T -> Optional<U>`, `flatMap` unwraps the value in the `Optional` and applies the function, except if either the source or target option was not present. It does exactly what the set-based `flatMap` would have done on sets with size 0 or 1.

Generally, when you design a type `G<T>` and a function `T -> U`, think whether it makes sense to define a `map` that yields a `G<U>`. Then, generalize to functions `T -> G<U>` and, if appropriate, provide `flatMap`.