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 ourF3
type thread safe?Generalize the
F3
type to a type that allows returning values other thanVoid
:struct F4<A, R> { let run: (@escaping (A) -> R) -> R }
. Definezip2
andzip2(with:)
on theA
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 layerOptional
haszip2
defined, but also the inner layerArray
has azip2
. Can we define azip2
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 ownzip2
operation. Can you define azip2
on this type that makes use of bothzip
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 ownzip2
operation. Can you define azip2
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 ownzip2
operation. Can you define azip2
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 ownzip2
operation. Can you define azip2
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, 2018Validated
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.