Composing Functors
Published: 2020-10-15 17:53:47


Functors are closed under composition. This means that we should be able to construct a well-behaved `map` method for the composition.

**Functors are closed under composition**. The term closed means that if we have two functors and we compose them (have a functor-in-a-functor situation like `Maybe<Id<>>` or `Maybe<Array<>>`, `Array<Array<>>` etc), the resulting structure is also a functor.

This means that we should be able to construct a well-behaved `map` method for the composition, using only the `map` methods of the composing functors and nothing more.

Let us examine some specific cases. We will start with the `Id<Array<>>` case. This is not a Type that you will see in practice but will make the mechanics easier to examine. It’s easy to get a `Id<Array<>>`. For example we can place some Clients in an Id<>:

```javascript
Id([new Client(1, "jim", 2), new Client(2, "jane", 3)]) 
```

now we can define a map for this composition easily

```javascript
var mapT = composite => f => composite.map(inner => inner.map(f))
```

```javascript
import { Client } from "./model.js"
import { Id } from "./Id.js"

let idClients =Id([new Client(1, "jim", 2), new Client(2, "jane", 3)]) ;

let mapT = composite => f => composite.map(inner => inner.map(f))

let idNames = mapT(idClients)(client=>client.name)

 console.log(idNames)  //Id (['jim', 'jane' ] ) 
                       //the result is an Id<Array[String]>
                       // -An Id of an Array of Strings
                       
 
```

​																																																[Run This](https://stackblitz.com/edit/composing-functors?file=index.js) 

You will use the map of each Functors to pass the function  `client=>client.name` one level deeper.
 It’s easy to see that this pattern `.map(_->_.map(_->_))` will appear in any combination of functors. Look at another combination just to confirm this. For an `Array<Array<>>`

```javascript
import { Client } from "./model.js"
 

let groupsOfClientsByDepartment = [
    [new Client(1, "jim", 2), new Client(2, "jane", 3)],
    [new Client(3, "kate", 2), new Client(4, "John", 3)]];

var mapT = composite => f => composite.map(inner => inner.map(f))

var groupsOfClientNamesByDepartment = mapT(groupsOfClientsByDepartment)(client => client.name)

console.log(groupsOfClientNamesByDepartment)  //[ [ 'jim', 'jane' ], [ 'kate', 'John' ] ]
                       //the result is an Array<Array[String]>
                       // -An Array of an Array of Strings 
```
 {% stackblitz composing-functors-afmpqz %} 

 [Run This](https://stackblitz.com/edit/composing-functors-afmpqz?file=index.js)

It is the same `.map(_->_.map(_->_)) ` pattern again.

## Transformer Types  

Another way to express this composition is by creating an adapter  that we usually refer to as “transformers” that would expose a single `.map(_)`

```javascript
export const ComposeT = composition => ({
  map: f => ComposeT(composition.map(inner => inner.map(f))),
  unwrap: () => composition
});
```

we can use this `IdArrayT` transformer in the following way :

 {% stackblitz composing-functors-transformer %} 

[Run This](https://stackblitz.com/edit/composing-functors-transformer?file=index.js) 

The main computation now becomes :
```javascript
let idNames = ComposeT(idClients)
                 .map(client => client.name)
                 .map(name => name.toUpperCase())
                 .unwrap();
```
*In the next sections we are going to use those ideas to deal with  the `Promise<Maybe<>>` and `Promise<Either<>>` combinations.

Excerpt from the free course https://www.fluidinfunctional.com/jscourse/ which is a self-standing subset of the book [“Functional Programming in Javascript”](https://leanpub.com/functional-programming-in-js-with-categories)
 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0oslgpbg2jtkxvlykrrc.png)
https://www.fluidinfunctional.com/jscourse/