So far in the book you’ve seen a number of different containers that add some effect to the underlying value(s)—Option for optionality, IEnumerable for aggregation, Task for asynchrony, and so on. As our list of containers keeps growing, we’ll inevitably hit the problem of combining different containers:
- If you have a list of Tasks that you want to execute, how can you combine them into a single Task that will complete when all the operations have completed?
- If you have a value of type Task<Validation<T>>, how do you compose it with a function of type T → Task<R> with the least amount of noise?
This chapter will give you the tools to combine the effects of different containers and show how to avoid an excess of nested containers.
Traverse is one of the slightly more esoteric core functions in FP, and it allows you to work with lists of elevated values. It’s probably easiest to approach through an example.