# I don't like curry

I don't like curry. Help me reverse the effects of this evil question - Make me some curry - by uncurrying functions.

# Task

• Given a blackbox curried function, output its uncurried equivalent.
• The curried function will take a single argument and output either another curried function or a value of another type.
• The uncurried function you create will take the same number of arguments as the curried function, but all at once.

# Rules

• In languages without first-class functions, you can use an object with a method in place of a curried function - but please specify this.
• The curried function may also output a function pointer instead.
• If your language does not allow function pointers or makes passing around functions hard to work with, but allows evaluating strings to make functions (e.g. APL), you can use strings to represent both curried functions and your uncurried output function.
• You can also take the number of arguments of the functions as an input to help you determine the depth of currying.
• You may choose to return a function that takes a tuple, list, or other single value containing all the arguments.
• You may constrain the arguments and return type to a data type of your choosing, but that type should have more than 1 possible value.
• If f is the inputted curried function and g is your uncurried function, f(a1)(a2)...(aN) must always equal g(a1, a2, ..., aN).
• The order of arguments in the uncurried function should be the same as in the original curried function.

For example, given the function a -> b -> c -> a + b + c, you can return a function that looks like (a, b, c) -> a + b + c or arr -> arr + arr + arr -> ... but not (c, b, a) -> ... (wrong order). If you also take the number of arguments of the function as input, then (a, b) -> c -> ... would be an acceptable output given the input 2 (2 arguments are curried).

# Bounty

Since Rust is the language of the month, I will be offering a 50 rep bounty on Rust answer to this question if you haven't used Rust before.

• Is there a limit to the number of arguments we must support? Haskell has a hard limit on tuple size (23 I think?). – Wheat Wizard Dec 28 '20 at 2:32
• By "Given a blackbox curried function, output its uncurried equivalent": The uncurry function receives two arguments, a function and its arguments, currying. – tsh Dec 28 '20 at 3:06
• What should happen in languages that allow polymorphic returns where the polymorphism may cover function types? For example, in Haskell, id :: a -> a can be also be called at the type id :: (a -> b) -> a -> b. Does id have one argument or two (or three or four or...)? – Daniel Wagner Dec 28 '20 at 4:56
• @vrintle that's not a curried proc... this is... (what i mean is, the builtin .curry is not what the question means by a curried proc.) – ASCII-only Dec 28 '20 at 10:49
• @user Would it? Or would it be the unchanged a -> a? Or would it be ((a -> b -> c), a, b) -> c? Or ((a -> b -> c -> d), a, b, c) -> d, or...? But okay, if I can expect the caller to specify the number of arguments, then the goal is more clear. – Daniel Wagner Dec 28 '20 at 16:33

# Python 3, 46 bytes

lambda g,i:lambda*l,g=g:eval(f'g{"(%a)"*i%l}')


Try it online!

# Python 3, 48 bytes

f=lambda g:lambda x,*a:f(g(x))(*a)if a else g(x)


Try it online!

• 47 bytes? – user Dec 27 '20 at 21:32
• @user no, because a and f(g(x))(*a) could evaluate to something falsey (like 0 or []) then or would cause an incorrect evaluation of g(x) returning a function (e.g. TIO). – Jonathan Allan Dec 28 '20 at 2:53
• Ah, that’s too bad. – user Dec 28 '20 at 3:33

# JavaScript (Node.js), 34 bytes

g=>(...a)=>a.reduce((h,x)=>h(x),g)


Try it online!

-1 byte, thanks to ASCII-only.

# JavaScript (Node.js), 31 bytes

g=>(...a)=>(a.map(x=>g=g(x)),g)


Try it online!

This 31 byte version, the returned function is not reusable. I'm not sure if this is allowed in this question...

• 34 – ASCII-only Dec 28 '20 at 8:20
• @ASCII-only Ahh, I wrote the one use reduce first. And find out using map is shorter. Later I noticed that the return value is not reusable. And I forgot to use reduce this time.... – tsh Dec 28 '20 at 8:28

# Haskell, 129 127 bytes, thanks to Wheat Wizard

{-#Language GADTs#-}
data N c u o where Z::N o()o;S::N c u o->N(i->c)(i,u)o
(!)::N c u o->c->u->o
(Z!o)_=o

# C++ (gcc), 189 bytes

#define T template
T<class F>struct U{F f;auto operator()(){return f;}T<class A,class...B>auto operator()(A a,B...b){return U<decltype(f(a))>{f(a)}(b...);}};T<class F>U<F>u(F f){return{f};}


Try it online!

Function u takes in a curried callable object, and returns another callable object which is uncurried.

(I don't see any allowance for a restriction on the return type of the curried function, just on the argument types. If it were allowed, we could save two bytes by replacing both instances of auto with int`.)