Expand in javascript a function of n parameters of n-parameters

If f :: a → b → c, then uncurry (f) can be defined as:

uncurry :: (a → b → c) → ((a, b) → c)

I am trying to implement the above function in javascript. Is my following implementation correct and general enough or is there a better solution?

const uncurry = f => { if (typeof f != "function" || f.length == 0) return f; return function() { for (let i = 0; i < arguments.length; i++){ f = f(arguments[i]); } return f; }; } const curry = f => a => b => f(a, b); const curriedSum = curry((num1, num2) => num1 + num2); console.log(curriedSum(2)(3)); //5 console.log(uncurry(curriedSum)(2, 3)); //5 
+5
source share
2 answers

There are three problems in your uncurry :

  • If not all expected arguments are passed, it returns a function in curry (which is not the behavior of a normal, unconfirmed function)
  • he cannot deal with unnecessary arguments
  • the implementation is not very functional as you are not reusing anything

Here is a more functional approach:

 const id = x => x; const uncurry = f => (x, y) => f(x)(y); const uncurryn = n => f => (...xs) => { const next = acc => xs => xs.reduce(uncurry(id), acc); if (n > xs.length) throw new RangeError("too few arguments"); return next(f) (xs.slice(0, n)); } const sum = x => y => z => x + y + z; try {uncurryn(3)(sum)(1, 2)} catch(e) {console.log(e.message)} console.log(uncurryn(3)(sum)(1, 2, 3)); console.log(uncurryn(3)(sum)(1, 2, 3, 4)); 

uncurryn ignores unnecessary arguments like any other function in Javascript. It reuses uncurry , reduce and id .

If too few arguments are passed, it throws an error, since in each case it is not clear which value should be returned ( NaN , undefined ).

+2
source

This is not bad, but you are assuming that f works until you complete all the arguments.

Also, if you are using es6, consider using a rest statement instead of arguments . And for ... of a nicer syntax in es6 for cyclic conversion of array values.

 const uncurry = f => { if (typeof f !== "function" || f.length == 0) return f; return (...args) => { for (let arg of args) { if (typeof f !== "function") { return f; } f = f(arg); } return f; }; } const curry = f => a => b => f(a, b); const curriedSum = curry((num1, num2) => num1 + num2); console.log(curriedSum(2)(3)); //5 console.log(uncurry(curriedSum)(2, 3)); //5 
+1
source

All Articles