### Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

### Introduction

In the last episode we began the journey into exploring the “many faces of zip”. First we played around with the `zip`

that the standard library gives us a bit and saw that it was really useful for coordinating the elements of two sequences in a very safe way so that we don’t have to juggle indices.

Then we zoomed out a bit and looked at the true signature of `zip`

, and we saw that what it was really doing was kinda flipping containers: it transformed a tuple of arrays into an array of tuples.

After that we saw that `zip`

is just a generalization of `map`

: where `map`

allows us to transform a function `(A) -> B`

into a function `([A]) -> [B]`

, `zip`

allowed us to transform a function `(A, B) -> C`

into a function `([A], [B]) -> [C]`

.

This empowered us to define `zip`

on optionals, which is not something that people typically do. It ended up being the perfect solution to a problem that plagued Swift 1: nested `if let`

s! Swift 2 fixed this, but `zip`

still can provide a more ergonomic solution than multiple `if let`

s on the same line.

### Subscribe to Point-Free

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

Already a subscriber? Log in

### Exercises

Can you make the

`zip2`

function on our`F3`

type thread safe?Generalize the

`F3`

type to a type that allows returning values other than`Void`

:`struct F4<A, R> { let run: (@escaping (A) -> R) -> R }`

. Define`zip2`

and`zip2(with:)`

on the`A`

type parameter.Find a function in the Swift standard library that resembles the function above. How could you use

`zip2`

on it?This exercise explore what happens when you nest two types that each support a

`zip`

operation.- Consider the type
`[A]? = Optional<Array<A>>`

. The outer layer`Optional`

has`zip2`

defined, but also the inner layer`Array`

has a`zip2`

. Can we define a`zip2`

on`[A]?`

that makes use of both of these zip structures? Write the signature of such a function and implement it. - Using the
`zip2`

defined above write an example usage of it involving two`[A]?`

values. - Consider the type
`[Validated<A, E>]`

. We again have have a nesting of types, each of which have their own`zip2`

operation. Can you define a`zip2`

on this type that makes use of both`zip`

structures? Write the signature of such a function and implement it. - Using the
`zip2`

defined above write an example usage of it involving two`[Validated<A, E>]`

values. - Consider the type
`Func<R, A?>`

. Again we have a nesting of types, each of which have their own`zip2`

operation. Can you define a`zip2`

on this type that makes use of both structures? Write the signature of such a function and implement it. - Consider the type
`Func<R, [A]>`

. Again we have a nesting of types, each of which have their own`zip2`

operation. Can you define a`zip2`

on this type that makes use of both structures? Write the signature of such a function and implement it. - Finally, conisder the type
`F3<Validated<A, E>>`

. Yet again we have a nesting of types, each of which have their own`zip2`

operation. Can you define a`zip2`

on this type that makes use of both structures? Write the signature of such a function and implement it.

- Consider the type
Do you see anything common in the implementation of all of the functions in the previous exercise? What this is showing is that nested zippable containers are also zippable containers because

`zip`

on the nesting can be defined in terms of zip on each of the containers.

### References

#### Validated

**Brandon Williams & Stephen Celis • Friday Aug 17, 2018**

`Validated`

is one of our open source projects that provides a `Result`

-like type, which supports a `zip`

operation. This means you can combine multiple validated values into a single one and accumulate all of
their errors.