Last active
February 24, 2017 20:54
-
-
Save MarkusPfundstein/c434d3aa4a4dde70eccd7ccd11bdb8b2 to your computer and use it in GitHub Desktop.
fluent_vs_composition_in_FL.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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