DEV Community

Discussion on: Writing a Functional Programming-Style map Function

Collapse
 
rpearce profile image
Robert Pearce

Hi, Brent! Thanks for reading and taking the time to ask a question.

To answer your question: not quite! Check out this example:

const add  = (a, b) => a + b
const add2 = add.bind(null, 2)
add2(3) // 5
add2(5) // 7

In this example, we save the result of partially applying the first argument to add in a variable called add2 and state that it should be 2. Because we did not apply all of the arguments that add needs and did this partial application using the .bind method, we get back a function that we can reuse over and over again (add2).

Here's the same function, but it is written using a manually curried function:

const add  = a => b => a + b
const add3 = add(3)
add3(2) // 5
add3(4) // 7

In this example, add takes 2 arguments before it returns a result, but the arguments are curried. add(3) applies the argument 3 to add, but since add needs to be called twice (depending on how you've curried it...see the article below on currying), add(3) will return a function that expects to be called with the final argument. That's what we do on the last two lines; i.e., partial application allows us to store the result of calling add with 3 and then add any number we want to with 3 over and over and over.

The mapId function above could work like const mapId = (m) => map(x => x.id)(m), but since calling map(x => x.id) already returns a function, and we are merely forwarding on the argument to another function, we can do an eta reduction (see presentation below) and simplify the code. Check it out:

const mapId = m => map(x => x.id)(m)
const mapId =      map(x => x.id)

This presentation has a bit of stuff on this subject (specfically slides 36-43):
slideshare.net/robertwpearce/a-pat...

I've also written some posts on currying and composition that might be helpful, too:

Collapse
 
brentc profile image
Brent C

but since calling map(x => x.id) already returns a function

Yes, that example works if map is returning a function, but I guess my read at that point in the article was that map wasn't returning a function.

  • it takes a function (fn) and then some datum (m2)3
  • it returns the datum as transformed by said function

In which case the example that follows that presupposes it's already a curried implementation was confusing.

Thread Thread
 
rpearce profile image
Robert Pearce • Edited

...aaaaand I feel like an idiot. I totally see it now! We're still working with (fn, m) => ... and not fn => m => ..., so that doesn't make sense yet. I'll update ASAP. Thanks for your patience, and nice 👀!

Thread Thread
 
rpearce profile image
Robert Pearce

Quick fix was to change it to:

const mapId = map.bind(null, x => x.id)

Thanks again.