5 Higher-kinded composition

 

This chapter covers

  • Transforming arrays and objects safely with map and flatMap
  • Composable design patterns with algebraic data types
  • Writing a Validation data type to remove complex branching logic
  • Chaining ADTs using the new bind operator (::)

The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.

—Edgar Dijkstra

In chapter 4, you learned how function composition leads to fluent, compact, and declarative code when you use compose to chain your function’s inputs and outputs as data passes through them. Composition has a lot of benefits because it uses JavaScript’s strongest feature, as I’ve said many times: higher-order functions. With functions, you can achieve low-level composition at the lowest unit of abstraction. But a higher-kinded composition also exists in the way objects compose. Making objects compose as strongly as functions do is a key idea that we’ll discuss in section 5.3.

5.1 Closing over data types

5.2 New Array APIs: {flat, flatMap}

5.2.1 Array.prototype.flat

5.2.2 Array.prototype.flatMap

5.3 The map/compose correspondence

5.4 Universal contracts

5.4.1 Functors

5.4.2 Monads

5.5 Contextual validation with higher-order functions

5.5.1 Kinds of ADTs

5.5.2 Choices

5.5.3 Modeling success and failure with the Validation monad

5.5.4 Composing with monads

5.5.5 Higher-kinded composition with Validation

5.5.6 Point-free coding with monads