Promise as Functor (Video)

Idea: The Promise then can be seen as a map method that applies a function to the expected value.
Async Id Functor
this is more of an idea i came up in order to make more obvious that a Promise is just an asynchronous identity functor ( or an async Either functor if you include an error callback) .
We already talk about how the Id entity functor is the minimal functor in a js world
const Id = (v) => ({
value: v,
map: (f) => Id(f(v))
});
It doesn’t matter if we don’t have the value yet since we can instead of the v leave a subscription callback that will eventually have the value so we can
const Id= (executor) => ({
map: (f) =>…
});
Which we will use in this way when we have a value
Id(r => r(5))
Now in order to create the map we still follow the same steps that we follow to create a map for a Functor

- Open the container and access the value v. We can access the value by adding a subscription to the callback like this
executor(v=>…)
now we have the value (whenever this value becomes available, we do not care .What matters to us is that we have a variable v to treat as a value) - Apply the function f
executor(v=>f(v))
- We must repackage this into something that is the same as the initial package
Id = (executor) => ({…})
Fortunately for us this form of Id expects a callback and not a value, so we have to pass on the constructor something that looks like thismap: (f) => Id(resolve => … )
this means that we can pass the valuef(v)
from executor(v=>f(v))
into the r and in this way we have completed the construction
What we get is the following:
var Id = (executor) => ({
map: f => Id(resolve => executor(v => resolve(f(v)))),
matchWith: pattern => executor(v => pattern(v))
})
Id(resolve => resolve(5)).map(x => x + 4).matchWith(console.log)
Promise as Functor
We will start by extending the Custom Promise seen previously to a functor, by providing a map method that obeys the functor laws and thus promote native Promise into a functor.
The Native implementation of promises (based on the Promises/A+ specification ) has a map achieved by overloading the then:
var thenableMapResult = new Promise((resolve,reject)=>resolve(5))
.then(x=>x+3)
.then(console.log)//8
Run This: Js Fiddle
This Section is clearly to just provide some understanding on the mechanics behind the .then as a map .
We have said that the usual metaphor for a functor is “a container.” A Promise can be seen as a container that takes a value and wraps it, until it is resolved. In order to promote Promise to Functor, there must be a mapping function that would be able to lift any function and give a new Promise with the lifted value.
Here is one possible mapping function that preserves structure:
Promise.prototype.map = function(f) {
var initialPromise = this;
return new Promise(function(resolve,reject) {
initialPromise.then(result => resolve(f(result)))
.catch(reject);
});
}
Run This: Js Fiddle
The mapping function that lifts the function f: a→b follows the steps:
- Waits for the result of the Promise (so in a way unwraps the contained value)
initialPromise.then( )
- Applying the function f :
result => resolve(f(result))
- wraps the resulting value again into a new Promise :
return new Promise()
because when we implement a map, we always return something of the same type in order to belong to the same category (in this case type) or Promise.
Something worth pointing out here is the .catch(reject) this part belongs to the path of failure and ignores the f mapping. We are going to come back to this observation many times throughout this book.
Get the full functional JavaScript bundle