Skip to content

Commit

Permalink
Rollup merge of rust-lang#30971 - SDX2000:docfixes, r=steveklabnik
Browse files Browse the repository at this point in the history
Updated documentation to clarify the difference between `and_then` and `map`. This also explains why we need `and_then` in addition to `map`. Please look at the diff for more information.

r?  @alexcrichton
  • Loading branch information
steveklabnik committed Feb 2, 2016
2 parents a4a249f + 0922d7e commit 78afc78
Showing 1 changed file with 26 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/doc/book/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,28 @@ fn file_name(file_path: &str) -> Option<&str> {
```

You might think that we could use the `map` combinator to reduce the case
analysis, but its type doesn't quite fit. Namely, `map` takes a function that
does something only with the inner value. The result of that function is then
*always* [rewrapped with `Some`](#code-option-map). Instead, we need something
like `map`, but which allows the caller to return another `Option`. Its generic
implementation is even simpler than `map`:
analysis, but its type doesn't quite fit...

```rust,ignore
fn file_path_ext(file_path: &str) -> Option<&str> {
file_name(file_path).map(|x| extension(x)) //Compilation error
}
```

The `map` function here wraps the value returned by the `extension` function
inside an `Option<_>` and since the `extension` function itself returns an
`Option<&str>` the expression `file_name(file_path).map(|x| extension(x))`
actually returns an `Option<Option<&str>>`.

But since `file_path_ext` just returns `Option<&str>` (and not
`Option<Option<&str>>`) we get a compilation error.

The result of the function taken by map as input is *always* [rewrapped with
`Some`](#code-option-map). Instead, we need something like `map`, but which
allows the caller to return a `Option<_>` directly without wrapping it in
another `Option<_>`.

Its generic implementation is even simpler than `map`:

```rust
fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
Expand All @@ -382,6 +399,10 @@ fn file_path_ext(file_path: &str) -> Option<&str> {
}
```

Side note: Since `and_then` essentially works like `map` but returns an
`Option<_>` instead of an `Option<Option<_>>` it is known as `flatmap` in some
other languages.

The `Option` type has many other combinators [defined in the standard
library][5]. It is a good idea to skim this list and familiarize
yourself with what's available—they can often reduce case analysis
Expand Down

0 comments on commit 78afc78

Please sign in to comment.