Skip to content

Instantly share code, notes, and snippets.

@kutyel
Last active August 5, 2019 20:51
Show Gist options
  • Save kutyel/818937bda1bf1f513ff63e517342d194 to your computer and use it in GitHub Desktop.
Save kutyel/818937bda1bf1f513ff63e517342d194 to your computer and use it in GitHub Desktop.
My own implementation of curry πŸ›
// Ultimate version
const curry = (f, ...args) =>
f.length <= args.length
? f(...args)
: x => curry(f, ...args, x)
@ericelliott
Copy link

ericelliott commented Oct 30, 2017

That version is not a full auto-curry.

Try this:

const curry = (fn, length = fn.length) => function curried (...args) {
  return args.length >= length ?
    fn(...args) :
    (...args2) => curried(...args, ...args2)
  ;
};

@ericelliott
Copy link

This is the version I've been using in examples:

const curry = (
  f, arr = []
) => (...args) => (
  a => a.length === f.length ?
    f(...a) :
    curry(f, a)
)([...arr, ...args]);

@kutyel
Copy link
Author

kutyel commented Oct 31, 2017

Awesome 😍 Thanks very much! I just noticed I need the second ...args in the recursive call to curried πŸ˜‰

@kutyel
Copy link
Author

kutyel commented Oct 31, 2017

I see what you did there with the default param, very clever! πŸ€“ I was actually looking for a way to return that lambda without the function keyword, and here I have my answer 😊

@rachelcarmena
Copy link

rachelcarmena commented Aug 5, 2019

Hi! I'm here because I watched again your talk about Lenses in Lambda World (again = I was there that day πŸ˜‰ ). Congrats for it!
I would like to know what do you think about these concerns:

  • The possibility of calling that function with more than one parameter. For example, a different arity could be passed.
  • The possibility of not having unary functions because of (...argz).

Here I have another version to avoid those things: https://gist.github.com/rachelcarmena/196b9f8b1c6b078b65fb1328f09c0269

What do you think about it? Do you think that my concerns make sense?

Thanks in advance!

@kutyel
Copy link
Author

kutyel commented Aug 5, 2019

Hi Rachel! Thanks for the compliments, I'm glad you like the talk! ☺️ I think you are right, what about this implementation?

const curry = (f, ...args) => f.length <= args.length ? f(...args) : x => curry(f, ...args, x)

The argz thing was added by @ericelliott, I don't really remember now why to be honest πŸ˜‚

@rachelcarmena
Copy link

Thanks @kutyel! I'd remove all the additional parameters. For example, this situation would be possible:

const sum = (a, b) => a + b;
const curriedSum = curry(sum);
const wrongCurriedSum1 = curry(sum, 2); // a function with one parameter
console.log(wrongCurriedSum1(3)); // 5
const wrongCurriedSum2 = curry(sum, 2, 3); // not a function, but 5
const wrongCurriedSum3 = curry(sum, 2, 3, 4); // not a function, but 5

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment