I’ve been working on making Ramda integrate with
Fantasy-land-style objects. Specifically, I added the
of to Ramda. These functions satisfy the
of is so trivial it appears almost useless. It simply wraps its argument in an array:
(The actual implementation of
of in Ramda checks if you have also passed in a Fantasy-land-style object
of method, and dispatches to that method–but that is beside the point for this discussion.)
ap on the other hand, seems so obscure that at first glance, it’s difficult even to see how you
would use it. In Ramda,
ap takes a list of functions (
fns), and a list of arguments (
apply the list of functions to. It returns an array of results from applying each function to each
argument. The output of
ap is like a cross-product of the
fns by the
args, with a length of
fns.length * args.length:
I added these functions to Ramda on faith; that is, even though I did not clearly see real-world use cases
for them, I trusted that these functions are useful. After all,
of can both be found in
of is called
pure in Haskell). And those Haskell folks are pretty sharp.
Then Thomas Deutsch left a comment on Scott’s blog post
Favoring Curry. He was working on a function
hasAllTags that takes a list of letters and returns
true if the passed in list contains all of
the letters in an array inside the function. In his posted example of
hasAllTags, the internal
Mr. Deutsch’s question: “How is it possible to construct this function only by composition or currying?”
Good question! Let’s take apart what this function is supposed to do:
['a', 'd']), see if the passed in list contains that letter
This is very close to
contains. The difference is that we need to apply
contains repeatedly, with different
And somehow we need to
and all of those results together to see if the whole expression is
So we want our composition to:
containsonce for each internal letter
Here we have a real use case for
ap: I can take my input list and apply a list of functions to it!
In this case, I am going to apply a list of
contains partially applied to each letter in the
I generate that list of functions by mapping over the internal letters and partially applying each one
contains. Ramda’s auto-curried functions makes this easy:
Then I take the list of functions from that mapping, and pass them to
ap. Of course,
also curried. I am giving just the list of functions to it:
This is the guts of the composition.
Given just the list of functions,
ap returns a function that is waiting for
a list of arguments to apply its list of functions to. And then
ap will return an array of results
of those applications. In this case, it will be an array of booleans.
The final step in the composition is to reduce that output array of booleans from
ap to a single boolean.
Simplest thing to do is to pass the output from
partially applied to the
All that remains to do is to prepare the original list to be input to this composition.
We can’t just pass a list of letters in. Recall that
ap will apply its array of functions to
each one of its list of arguments. If we passed in the array
['a', 'b', 'c', 'd'],
would call each function four times! Worse than that, we have partially applied
ap, and those functions are expecting an array, not a string.
In other words, we want to pass the input array inside the arguments list to
The solution is to wrap the input in an array. That is exactly what
of does. So the complete
composition of the
hasAllTags function is:
Hey, those Haskell folks are pretty sharp!
You can find
of and many more
fun functions in Ramda 0.3.0. Please take it for a spin.