# The Many Faces of Flat‑Map: Part 1

Episode #42 • Jan 7, 2019 • Subscriber-Only

Previously we’ve discussed the `map` and `zip` operations in detail, and today we start completing the trilogy by exploring `flatMap`. This operation is precisely the tool needed to solve a nesting problem that `map` and `zip` alone cannot.

###### Previous episode
The Many Faces of Flat‑Map: Part 1
Introduction
00:05
The need for flat‑map
02:19
Nesting problems on other types
09:44
Swift's flat‑maps
20:23
Till next time
24:05

### Introduction

We’re back for our first episode of 2019. Hope everyone had a nice break, and we’re ready to start some new material.

The title of this episode is “the many faces of `flatMap`”, and if you’ve been a following Point-Free for awhile you may know that we’ve done this style of episode twice before. First we did “The Many Faces of Map”, where we showed that `map` is a very universal operation that goes far beyond the `map` that Swift defines on sequences and optionals. It’s in fact the unique function with its signature that satisfies a simple property, and that tells us that `map` isn’t something we invent but rather something we discover. It was there all along whether or not we knew it. This empowered us to define `map` on many new types, which unlocks a lot of nice compositions.

A few months after that we did a 3-part series of episodes called “The Many Faces of Zip” (part 1, part 2, part 3), where we similarly showed that `zip` can also be generalized far beyond the `zip` that is defined on sequences in the Swift standard library. We could define `zip` on optionals, result types, function types, and even asynchronous values. We also saw that `zip` allows you to do `map`-like operations, but just with functions that take more than one argument, which is simply not possible with `map` alone. So `zip` unlocked something new for us.

Today’s episode completes a trilogy of operations, and honestly it’s kind of shocking that Point-Free launched nearly a year ago and this is our first time talking about it. I think a lot of people would assume this topic is the bread and butter of functional programming, and although quite important, in our 41 previous episodes so far we have shown that you can still do a lot without it.

We are of course talking about `flatMap`!

Swift ships with two `flatMap` methods, one on sequences and one on optionals, but the idea of `flatMap` is so much bigger than just that. It is a further generalization of the ideas of `map` and `zip` in that it can express things that are just not possible with `map` and `zip` alone. So today we begin to get comfortable with `flatMap` and expand our understanding of what its true purpose is.

We try to make episodes stand on their own as much as possible, but `flatMap` is so intimately related to `map` and `zip` that this just isn’t possible to do. We think you’ll get the most from this episode if you’ve seen our previous episodes on `map` and `zip` (part 1, part 2, part 3) because we are building off of those ideas quite a bit.

This episode is for subscribers only.

### Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

### Exercises

1. In this episode we saw that the `combos` function on arrays can be implemented in terms of `flatMap` and `map`. The `zip` function on arrays as the same signature as `combos`. Can `zip` be implemented in terms of `flatMap` and `map`?

2. Define a `flatMap` method on the `Result<A, E>` type. Its signature looks like:

``````(Result<A, E>, (A) -> Result<B, E>) -> Result<B, E>
``````

It only changes the `A` generic while leaving the `E` fixed.

3. Can the `zip` function we defined on `Result<A, E>` in episode #24 be implemented in terms of the `flatMap` you implemented above? If so do it, otherwise explain what goes wrong.

4. Define a `flatMap` method on the `Validated<A, E>` type. Its signature looks like:

``````(Validated<A, E>, (A) -> Validated<B, E>) -> Validated<B, E>
``````

It only changes the `A` generic while leaving the `E` fixed. How similar is it to the `flatMap` you defined on `Result`?

5. Can the `zip` function we defined on `Validated<A, E>` in episode #24 be defined in terms of the `flatMap` above? If so do it, otherwise explain what goes wrong.

6. Define a `flatMap` method on the `Func<A, B>` type. Its signature looks like:

``````(Func<A, B>, (B) -> Func<A, C>) -> Func<A, C>
``````

It only changes the `B` generic while leaving the `A` fixed.

7. Can the `zip` function we defined on `Func<A, B>` in episode #24 be implemented in terms of the `flatMap` you implemented above? If so do it, otherwise explain what goes wrong.

8. Define a `flatMap` method on the `Parallel<A>` type. Its signature looks like:

``````(Parallel<A>, (A) -> Parallel<B>) -> Parallel<B>
``````
9. Can the `zip` function we defined on `Parallel<A>` in episode #24 be implemented in terms of the `flatMap` you implemented above? If so do it, otherwise explain what goes wrong.

### References

#### Railway Oriented Programming — error handling in functional languages

Scott Wlaschin • Wednesday Jun 4, 2014

This talk explains a nice metaphor to understand how `flatMap` unlocks stateless error handling.

When you build real world applications, you are not always on the “happy path”. You must deal with validation, logging, network and service errors, and other annoyances. How do you manage all this within a functional paradigm, when you can’t use exceptions, or do early returns, and when you have no stateful data?

This talk will demonstrate a common approach to this challenge, using a fun and easy-to-understand “railway oriented programming” analogy. You’ll come away with insight into a powerful technique that handles errors in an elegant way using a simple, self-documenting design.

#### A Tale of Two Flat‑Maps

Brandon Williams & Stephen Celis • Tuesday Mar 27, 2018

Up until Swift 4.1 there was an additional `flatMap` on sequences that we did not consider in this episode, but that’s because it doesn’t act quite like the normal `flatMap`. Swift ended up deprecating the overload, and we discuss why this happened in a previous episode:

Swift 4.1 deprecated and renamed a particular overload of `flatMap`. What made this `flatMap` different from the others? We’ll explore this and how understanding that difference helps us explore generalizations of the operation to other structures and derive new, useful code!