Last active
January 12, 2017 04:22
-
-
Save philipyoungg/a0ab1efff1a9a4e486802a8fb0145d9e to your computer and use it in GitHub Desktop.
Understand how lift works on function level
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
As I have hard time understanding the same issue, I decided to take a peek from Ramda's source code. Will write a blogpost about `this`. Meanwhile—I made a commented gist how Ramda's `lift` work step by step. | |
from: https://gist.github.com/philipyoungg/a0ab1efff1a9a4e486802a8fb0145d9e | |
// Let's make an example function that takes an object and return itself. | |
// 1. Ramda's lift level | |
lift(zipObj)(keys, values)({a: 1}) // returns {a: 1} | |
// this is how lift works in the background | |
module.exports = _curry2(function liftN(arity, fn) { | |
var lifted = curryN(arity, fn); | |
return curryN(arity, function() { | |
return _reduce(ap, map(lifted, arguments[0]), Array.prototype.slice.call(arguments, 1)); // found it. let's convert no 1 to no 2 | |
}); | |
}); | |
// 2. Ramda's reduce level | |
reduce(ap, map(zipObj, keys))([values]) | |
// This time, I'm taking reduce implementation that is not from Ramda (because honestly I can't understand it) but it should work similarly. | |
// credits to carlsednaoui => https://gist.github.com/carlsednaoui/5959036 | |
Array.prototype.reduce = function(fn, acc) { | |
if (acc === undefined && this.length !== 0) | |
return this.slice(1).reduce(fn, this[0]); | |
if (this.length === 0) return acc; | |
return this.slice(1).reduce(fn, fn(acc, this[0])); | |
}; | |
// 3. Ramda's ap level | |
ap(map(zipObj, keys), values) | |
// how ap works in the background | |
module.exports = _curry2(function ap(applicative, fn) { | |
return ( | |
typeof applicative.ap === 'function' ? | |
applicative.ap(fn) : | |
typeof applicative === 'function' ? // | |
function(x) { return applicative(x)(fn(x)); } : // because the first argument is a function, ap return this. | |
// else | |
_reduce(function(acc, f) { return _concat(acc, map(f, fn)); }, [], applicative) | |
); | |
}); | |
// 4. Voilà. Here's the final result. | |
map(zipObj, keys)({a: 1})(values({a: 1})) | |
// Hope it helps you and everyone else! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment