Looking at the source for Ramda.js, specifically at the "lift" function.
Here's the given example:
var madd3 = R.lift(R.curry((a, b, c) => a + b + c));
madd3([1,2,3], [1,2,3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]
So the first number of the result is easy, a
, b
, and c
, are all the first elements of each array. The second one isn't as easy for me to understand. Are the arguments the second value of each array (2, 2, undefined) or is it the second value of the first array and the first values of the second and third array?
Even disregarding the order of what's happening here, I don't really see the value. If I execute this without lift
ing it first I will end up with the arrays concat
enated as strings. This appears to sort of be working like flatMap
but I can't seem to follow the logic behind it.
Bergi's answer is great. But another way to think about this is to get a little more specific. Ramda really needs to include a non-list example in its documentation, as lists don't really capture this.
Lets take a simple function:
var add3 = (a, b, c) => a + b + c;
This operates on three numbers. But what if you had containers holding numbers? Perhaps we have Maybe
s. We can't simply add them together:
const Just = Maybe.Just, Nothing = Maybe.Nothing;
add3(Just(10), Just(15), Just(17)); //=> ERROR!
(Ok, this is Javascript, it will not actually throw an error here, just try to concatenate thing it shouldn't... but it definitely doesn't do what you want!)
If we could lift that function up to the level of containers, it would make our life easier. What Bergi pointed out as lift3
is implemented in Ramda with liftN(3, fn)
, and a gloss, lift(fn)
that simply uses the arity of the function supplied. So, we can do:
const madd3 = R.lift(add3);
madd3(Just(10), Just(15), Just(17)); //=> Just(42)
madd3(Just(10), Nothing(), Just(17)); //=> Nothing()
But this lifted function doesn't know anything specific about our containers, only that they implement ap
. Ramda implements ap
for lists in a way similar to applying the function to the tuples in the crossproduct of the lists, so we can also do this:
madd3([100, 200], [30, 40], [5, 6, 7]);
//=> [135, 136, 137, 145, 146, 147, 235, 236, 237, 245, 246, 247]
That is how I think about lift
. It takes a function that works at the level of some values and lifts it up to a function that works at the level of containers of those values.