I know I tackled this in another post, but it was more of an aside. I really want to give focus to the awesome dream team, buddy cop movie, and super-hero super-group that is
I've warmed up to the ramda library again (for reasons I'll get into later :) ), so I'll be using it for the following examples.
Here's a refresher on how
var R = require('ramda') var add3 = R.curry((a, b, c) => a + b + c) //all of these return 6 add3(1, 2, 3) add3(1)(2, 3) add3(1, 2)(3) add3(1)(2)(3)
curry takes a function and returns a curried version of it. A curried function takes all or some of its arguments.
If you give it all of its arguments, it returns normally. If you only give it some of its arguments, it returns a version of itself preloaded with those arguments and ready to take the rest.
var add2 = add3(0) add2(1, 2) //returns 3
What's cool is that ramda auto-curries it's functions:
var doubles = R.map((x) => 2 * x) var evens = R.filter((x) => x % 2 === 0) var sum = R.reduce((x, y) => x + y, 0) doubles([1, 2, 3, 4, 5]) //returns [ 2, 4, 6, 8, 10 ] evens([1, 2, 3, 4, 5]) //returns [ 2, 4 ] sum([1, 2, 3, 4, 5]) //returns 15
compose takes a list of functions and composes them, like so:
var f = (x) => 2 * x var g = (x) => x + 1 var h = (x) => x / 2 var fogoh = R.compose(f, g, h) fogoh(2) //returns 4
compose(f, g, h) returns a function that returns
curry + compose
So, how well do
curry work together? Check it out:
var comma_separate = (width) => R.compose( R.join(','), R.map(R.reverse), R.reverse, R.splitEvery(width), R.reverse) var format_dollars = R.compose( R.concat('$'), comma_separate(3), R.toString) format_dollars(100000) //returns $100,000
comma_separate starts by taking a string and reversing it with
R.reverse. Here's how it works in our example:
Then we split that string into 3's with
3 in this case):
[ '000', '001' ]
Note that since
R.splitEvery is auto-curried we can preload it with
width. This way it only takes one parameter, allowing us to fit it into our composition chain.
Next we reverse the array again with
[ '001', '000' ]
Then reverse each element in the array with
[ '100', '000' ]
Again, since we pre-load
R.reverse the function
R.map(R.reverse) only takes one more argument, allowing it to be a link in our composition chain.
Finally we join the string pretty much the same way we split it, taking advantage of currying again with
format_dollars then uses
concat to finish the job (again, taking advantage of currying):
You can keep adding functionality this way. Check out
var format_dollars_cents = R.compose( R.join('.'), (money) => [ format_dollars(money), money ? money.slice(0, 2) : '00'], R.split('.'), R.toString) format_dollars_cents(100000) //returns $100,000 format_dollars_cents(100000.234) //returns $100,000.23 format_dollars_cents(.234) //returns $0.23