Skip to content

Instantly share code, notes, and snippets.

@MarkusPfundstein
Last active February 24, 2017 20:54
Show Gist options
  • Save MarkusPfundstein/c434d3aa4a4dde70eccd7ccd11bdb8b2 to your computer and use it in GitHub Desktop.
Save MarkusPfundstein/c434d3aa4a4dde70eccd7ccd11bdb8b2 to your computer and use it in GitHub Desktop.
fluent_vs_composition_in_FL.js
/*
* According to the applicative functor laws, any applicative functor F must satisfy the composition law:
*
* pure (.) <*> F (+ 2) <*> F (* 2)
* ===
* F (+ 2) <*> (F (* 2) <*> F 3)
*
* Let's see how we can show this with two Applicative Functors. Data.Task from folktale and Fluture.
* Data.Task implements the pre v1.0 spec of fantasy-land, while Fluture is up to date.
*
* Context:
* In pre v1-spec the .ap spec was:
*
* Functor.of(function).ap(Functor.of(value))
*
* which was changed in v1 to
*
* Functor.of(value).ap(Functor.of(function))
*
* for some reasons :-).
*
* In order to show that the laws holds, it is not possible to use the Fluent API of Fluture. We need to
* use the static Future.ap method.
*
* For Data.Task, we can just use its fluent API.
*
* I'd argue that the Fluent API is much more easy to read and also much more in-line with javascript conventions...
*
* What do you think?
*/
const Task = require('data.task');
const Future = require('fluture');
// some helpers
const log = console.log;
const logE = (...x) => console.error('Error: ', ...x);
const plus = x => y => x + y;
const mult = x => y => x * y;
const compose2 = x => y => z => x(y(z));
// left hand side of composition law with Fluent and Task
// pure (.) <*> F (+ 2) <*> F (* 2) <*> F 3
Task.of(compose2)
.ap(Task.of(plus(2)))
.ap(Task.of(mult(2)))
.ap(Task.of(3))
.fork(logE, val => log(`taskLHS: ${val}`))
// Task(8)
// right hand side of composition law with Fluent and Task
// F (+ 2) <*> (F (* 2) <*> F 3)
Task.of(plus(2))
.ap(
Task.of(mult(2))
.ap(Task.of(3)))
.fork(logE, val => log(`taskRHS: ${val}`))
// Task(8)
// left hand side of composition LAW with S.ap and Future
// pure (.) <*> F (+ 2) <*> F (* 2) <*> F 3
Future.ap(
Future.ap(
Future.ap(
Future.of(compose2),
Future.of(plus(2))),
Future.of(mult(2))),
Future.of(3))
.fork(logE, val => log(`futureLHS: ${val}`))
// => Future(8)
// right hand side of composition law with S.ap and Future
// pure (.) <*> F (+ 2) <*> F (* 2) <*> F 3
Future.ap(
Future.of(plus(2)),
Future.ap(
Future.of(mult(2)),
Future.of(3)))
.fork(logE, val => log(`futureRHS: ${val}`))
// => Future(8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment