[Question]
  [
Having a function *f* that takes arguments *x1*, *x2*, …, *xn*
                                               – ie.  *f : X1 × X2 × … × Xn → Y*
– [currying](https://en.wikipedia.org/wiki/Currying) redefines *f* as a function taking a single argument *a1* which maps to yet another function. This technique is useful for partial application, for example with a curried `pow` function we could write `exp = pow(e)`.
### Example
Assuming we have the following function *f* taking three arguments (*f : X1 × X2 × X3 → Y*):
```
def f(a,b,c):
  return a + b * c
```
Currying this function leaves us with *f\_curry: X1 → (X2 → (X3 → Y))*, if we would now call that function twice with `f_curry(1)(2)` we would get a function (`h`) equivalent to the following returned:
```
def h(c):
   return 1 + 2 * c
```
The curried function `f` could be written like this (Python 3):
```
def f_curry(a):
  def g_curry(b):
    def h(c):
      return a + b * c
    return h
  return g_curry
```
[Try it online!](https://tio.run/##lZFfS8MwFMXf8ykO7CFJV8VuUqToo99AfFEZaZf@wS4rSSoO2WevSZe1E0GwD83Juef@btN0B1vv1XoYtrJEuSl6rQ9M8IwA3qmCk4/OyatZEXaAlrbXCgJL5IhQkAuzJpMMGEKIXxtp8IAXV6ZhIo0xPwtY8e4iCYSu@p1UNg4cg7JXhW32ykcaVWEFdiJu@ZQ2F2CW8Jn9H/Cc@UljqzPwL5rqd7nUvzrZemxeoGyUaCE/Oy2NcVMzR1m6w0RYk7eh042yjD5OZeqKdxGFX@mzaHvpVZqcradDJ1/HVHKziugV5YSUez0eamOsRqMQfry/OG@7C5AfomXnCHd@mPuV4T5JzRHwKr0d1ZFeO@JO2KkjhnuNOx7Dui84ac6Hbw "Python 3 – Try It Online")
## Challenge
Your challenge will be to curry a function as described above, here are the rules:
* Input will be a [blackbox function](https://codegolf.meta.stackexchange.com/a/13706/48198) which takes at least 2 arguments
* The input function will always have a fixed number of arguments (unlike `printf` or similar, note: you need to support functions with any number of arguments ≥2)
* If your language uses curried functions by default (eg. Haskell), you may expect the input function to be defined over *N*-tuples, instead of a "higher-order function"
* You may take the number of arguments as input
* Output will be the input's curried equivalent\*
* You may assume that the output function will only ever be:
	+ called with less or equal to the number of arguments that the input function takes
	+ called with arguments of the right type
---
\* This would mean for an input `f` with `N` arguments and an output `h` that for all valid arguments `a1,…,aN` it holds that `f(a1,a2,…,aN) == h(a1)(a2)…(aN)`.
  
[Answer]
## JavaScript (ES6), 35 bytes
```
f=g=>g.length<2?g:a=>f(g.bind(f,a))
```
[Answer]
# [Idris](https://www.idris-lang.org/), 204 bytes
```
import Data.HVect
C:(a:Vect n Type)->(HVect a->Type)->Type
C[]T=T[]
C(h::t)T=(x:h)->C t(T .(x::))
c:{a:Vect n Type}->{T:HVect a->Type}->((b:HVect a)->T b)->C a T
c{a=[]}f=f[]
c{a=h::t}f=\v=>c(\u=>f(v::u))
```
[Try it online!](https://tio.run/##VY0xb4MwFIR3/4pTJjtAlmSyZC90aKWqHWp1IR6MgeAhgIhJW6H8dmpoqiTLe3f3Tt9zRe9O0@SOXdt7PBlvNs@fpfUk5dTwWaGB@ulKlki6XGASeQ3mRdJMK6EyTVJac@6ZEvSb1@GawlOFTXCcMWL5@MC7JHJU/IEYIkrz/2zmI184BorY0YhMXypRhVezmZ8Fuz8Lael@ELKiZ84HxqahsUPfu7IAxx8sezM@xjI@fO@ag0Yir5Lc6pmJkcewGgKnuv0CNWuDCPk6Z4giWEKOxjX85Z2yRYmiJUAXMP61Ab0jbWPsYqx8vdLsvmJxK22xWxps@gU "Idris – Try It Online")
Sounds like a job for dependent types! Well, maybe.
---
**C** is a currying type function. Given a vector of types **a = [t1, t2, … tn]** and a type function **T : HVect a → Type**, it returns a new type:
> 
> 　　　　　　　　　　　**(x1 : t1) → (x2 : t2) → … → (T [x1, x2, … xn])**
> 
> 
> 
Here, **HVect** is the [heterogeneous vector type](https://www.idris-lang.org/docs/current/base_doc/docs/Data.HVect.html) from the Idris Prelude — the type of *n*-tuples whose elements are of *n* different types.
**c** is a function that takes **a** and **T** as implicit arguments, and then converts an *uncurried* function `f` of type **((b : HVect a) → T b)** into a *curried* one of type **C a T**.
(**C** simply describes what we wish to do; **c** actually does it. But we can't get away with not defining **C**, as Idris demands that every top-level definition have a type signature.)
---
The TIO link gives a usage example. If we define a function on 3-tuples **(Nat, Nat, String)** as follows:
```
uncurried : HVect [Nat, Nat, String] -> String
uncurried [a, b, c] = show (a*a + b*b) ++ c
```
then **`uncurried [3, 4, "th"]`** yields the same result as **`c uncurried 3 4 "th"`**. Idris infers the arguments `a=[Nat, Nat, String]` and `T=const String` for us, I believe.
I based this code on [this gist](https://gist.github.com/timjb/6258302) by timjb.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~54~~ 53 bytes
```
c=lambda n,f,*x:lambda y:(f,c)[n>1](*1%n*(n-1,f)+x,y)
```
[Try it online!](https://tio.run/##LctBCsIwEEDRtTnFbISZdLqIRZBAvYi4SNIOCjotIUJz@thFlx/eX2t5LTq0lsZP@MYpgLKw3fxR1aNwoofe3ROtO6tF7R0LdRtXatMsIBg47sabU57LLysE6CCChWTMmt9aMOGwL3ghvBLeiNof "Python 3 – Try It Online")
[Answer]
# [R](https://www.r-project.org/), 96 bytes
```
y=function(f,n=length(formals(f)),p=list())function(x,u=c(p,x))`if`(n<2,do.call(f,u),y(f,n-1,u))
```
[Try it online!](https://tio.run/##ZcxNCsIwEIbhfU8x4GZGp2q0BZXmLqZpooWYlNpCi3j2Gn8QxFnN4vnedppGaXuvuzp4tOylM/7UndGG9qLcFS0RN9LV1w6JvnDgXmpseCA61vaIvthwFZZaORcjPfH4bKUivjTZEKBI4TtWXLImuIGCBZQwBw33pFTtP@LqzdIPW0F1T2I6BMKccEO4JXjdDMzQGN2Z6gBCRBN7hGK9JsxeMKcfs98ts2R6AA "R – Try It Online")
---
[Previous version (97 bytes)](https://tio.run/##PYxBDsIgFAX3nuIv/1NqYo27chiKoCTIbwokbYxnx3bT5SQzM7e2al@TLUESe5V0dOlV3uxl/piY2QNq0jHkwsAhLqpqy5NagOA5DT2ecrUmxm1R4WJ2p3W/dbcNmxehoaOjNmpUFvQlQxca6UyWfrsvAn6Ae/Ad7Q8 "R – Try It Online")
-1 byte thanks to @JayCE
[Answer]
# [Coconut](http://coconut-lang.org/), 54 bytes
```
def c(f,*a):
 try:return f(*a)
 except:return c$(f,*a)
```
[Try it online!](https://tio.run/##NY1BCoAgFAX3nuItWvxftqh2Qt3FfgptLEShoLubEG2HYUYOOUJOpWzOQ8jr1rJRSPE20aUcAzxVpOAucWf6oTSfWjxmkNWrFka/wKLDihaiVI0xDUwj08R4FpxxD3X0Ag "Coconut – Try It Online")
---
# [Coconut](http://coconut-lang.org/), 40 bytes
Port of [Erik's Python answer](https://codegolf.stackexchange.com/a/162240/64121).
```
def c(f,n,*a)=n and c$(f,n-1,*a)or f(*a)
```
[Try it online!](https://tio.run/##FYwxDoAgEAR7X7GFxR1igdTwFzglsTkM0c6/o1STTDIjVao@d@/7USBUrFqTOCiS7pB5iNUNVRsK/ewFAZRstsJYIxIWZBjINI3cMzmmjckz3oirnfrPPw "Coconut – Try It Online")
[Answer]
# C++~~17~~ 20, ~~214~~ ~~200~~ ~~189~~ 184 bytes
```
#include<regex>
template<class R,class A,class...B>auto c(std::function<R(A,B...)>f){if constexpr(sizeof...(B))return[=](A a){return c<R,B...>({std::bind_front(f,a)});};else return f;}
```
[Try it on Wandbox](https://wandbox.org/permlink/tHGtWjVuRWMc4hlv) (TIO doesn't support gcc 9+ which is needed for std::bind\_front)
This is a template function that takes an std::function of any arity/type and returns a curried lambda expression. Uses constexpr if FTW. If any template gurus have any idea how to eliminate or reduce the need for std::function let me know.
Edit: replaced inner lambda with std::bind\_front.  
Edit: replaced include with shorter <regex>
Ungolfed version:
```
#include <functional>
template <class R, class A, class... B>
auto curry(std::function<R(A, B...)> f) {
    if constexpr(sizeof...(B) > 0) {
        return [=](A a) {
            return curry(std::function<R(B...)>{std::bind_front(f, a)});
        };
    } else {
        return f;
    }
}
```
[Answer]
# [Python 2](https://docs.python.org/2/), 60 bytes
```
c=lambda f,n,l=[]:lambda a:n-1and c(f,n-1,l+[a])or f(*l+[a])
```
[Try it online!](https://tio.run/##PYxNCsIwFIT3PUV2SeyrUN0FepKQxTM/WIkvIaZQj@UZPFhUrG5mvo@Byfd6TnRozU4RryeHLABBnLRRm6OiYURyzIr3NIwQe41GpsKC2H255TJTZcW7xXrx/1lVEKsEbcVMealCwtbS9D9qt1r2xeeI1nfHTvMLRsyeEgfG6RPPBzcv "Python 2 – Try It Online")
The footer is a tester which uses STDIN in the following way per line:
1. The function itself
2. The number of the function's arguments, ≥2
3. A list of the arguments (`[a,b,...]`)
Note that, while a list of the arguments is given as input in the tester, in reality, the curried equivalent gets prepended to the list and the list is reduced by function call.
A similar 55-byte version has been kindly provided by [ovs](https://codegolf.stackexchange.com/users/64121/ovs):
```
c=lambda f,n,*l:lambda a:n-1and c(f,n-1,*l,a)or f(*l,a)
```
[Try it online!](https://tio.run/##VYxBCsIwEEX3niK7zGgqlO4KnqSUMKYpVtJJSFOpx/IMHiy2ooKbz388eOGeLp6rnM3J0XjuSPSK1d7VH6Kai5K4EwZWUZSrUoQ@ih7eL4c4cAKthzH4mLQG2c9skvdukniMtpuNhV96qXtYUDUG7I0cDBzmBIhqa3wB28OfRMxTimsqODJ2V@0aeSVHwbKXSkje5vmQ7Qs "Python 3 – Try It Online")
[Answer]
# [Attache](https://github.com/ConorOBrien-Foxx/attache), 5 bytes
```
Curry
```
[Try it online!](https://tio.run/##SywpSUzOSP2fbGX737m0qKjyP1diSkp0hY5CZayCla1ChYK2QiVIyBgspqNQhRAG4iqugKLMvJLo5Gigkthoo9ho49hYZDHj2GjD2GiT2GhzoDhXbkF0Hlh/mH4eXBVQEKgpOhqIlRKVwCb8BwA "Attache – Try It Online")
Simple built in, largely uninteresting. But, here's a version from scratch:
## Attache, 35 bytes
```
{If[#__2<#_,Fold[`&:,$'__],_@@__2]}
```
Explanation:
```
{If[#__2<#_,Fold[`&:,$'__],_@@__2]}
{                                 }    lambda
 If[       ,              ,      ]     if
    #__2                                 the number of parameters after the first
        <#_                              is less than the arity of the first
            Fold[   ,    ]             then fold:
                 `&:                     right-function bonding
                     $                     over this function
                      '__                  paired with the rest of the parameters
                          ,            otherwise:
                           _@@           call the first parameter
                              __2        with the rest of them
```
[Answer]
# [Rust](https://www.rust-lang.org/), 73 69 bytes
```
macro_rules!c{($f:tt$(($n:tt:$a:ty))*)=>{$(move|$n:$a|)*$f($($n),*)}}
```
[Try it online!](https://tio.run/##PcpBDoMgEIXhfU@BySxmDF1odzT2KoYaSEwEU0CDEc9O0SadxbzF97vFh5yNHNzcu2VSvhp2BC1CAESwZQVIETaimrrXDmjmVaUCIBPVoBFKRbym48jaMiNHi7TfWLlJBRZZx1IU46Pl2/lTvG/Pv@qiQ4UR5WmE72voF0jvlQu9@pxBw1viGhvCy4/8BQ)
Rust is statically typed and because of this taking in a function with an unknown number of arguments is not allowed. Fortunately, macros have no such restrictions. This macro takes in a function of the form `name(arg1:type1)(arg2:type2)...(argN:typeN)`. and outputs a function that outputs an appropriately long chain of `impl FnOnce`s that ends with the desired function call. I shaved a few bytes by changing the input form to something more natural with the question. Ungolfed version:
```
macro_rules! c{       //declare a macro named c
  (                   //match on
    $f:tt             //A token tree (should be an ident, but this is codegolf)
    $(                //followed by zero or more sequences of
      ($n:tt : $a:ty) //a token tree (again, should be ident) colon type in parentheses
    )*                //end repetition
  )=>{                //replace with
    $(move|$n:$a|)*   //FnOnce closure heads for every matched name:type
    $f(               //call initially matched function
      $($n),*         //with a comma separated list of closure argument names 
    )                 //end call
  }                   //end rule
}                     //end macro
```
[Answer]
# [Cauliflower](https://github.com/broccoli-lang/broccoli), 84 bytes
```
(:= c(\($f$n(@a))(if$n(\($a)(call c(cat(list$f(-$n 1))@a(list$a))))else(call$f@a))))
```
[Try it online!](https://tio.run/##LYy9CsMwDIRf5QYNEqVD2i1Q8IN0EaoNBuEUx6GP7zpupzu@@zE9PCffPrH2zusDxk@mRIWDinA@3QAqbOo@UtPGnvdGia9UsIgE/YHRF4m@x1mlFCbo/K65NHCNr8Mi5j2oCP46zDkHGy64Cxbchkj/Ag "Cauliflower – Try It Online")
[Answer]
# Java 8, 19 + 126 = 145 bytes
This is a curried (hah) lambda taking a function and an argument count and returning the curried function.
```
import java.util.*;
```
```
f->p->new C(){List a=new Stack();public Object f(Object r)throws Throwable{a.add(r);return a.size()<p?this:f.f(a.toArray());}}
```
[Try It Online](https://tio.run/##fVJLbxoxED7DrxjlEjsFp0lu3UBFkSpVatUDuUUchl0vGLy2a3sXbdH@djK7LAJFaS/jh@bxPWaLFY6tk2ab7Y6qcNZH2NKfKKPS4i4ZDpWJ0ueYSpiZ@ntp0qisgcNw8Hu1lWmEnJ0ur0tAvw4c4sbbfYCX9sCVlsmwue4y/6C2rfxHoStXWqWQagwBfqHqRoeIkT4vQPMelzgDfL4CO/pv4g9CtpZ@BPPpFNLS@xomx3w8deOpkXuYM374qQJBnLTPRcR0x3jSw3rPw/P3JA4oMMuY54mXsfQGUAT1VzL@7L7GjQpfcpEzFNHOvMeacZ40zXFAug/6ET3XyqoMCuLPFtErsya529fsQ8lbjQbXdinjyggTuHjlcX@qHU@77MH9PdVLL28DGAs3FXqFGQ1eSyO9SsPNCIKFvYQNVhKiBVdqDbb0ne10iWBzQCLYEhF9y2/0nVlzG2FvSdoEVA61LSH8KWklQEXip6iPtnYXILWF0zJKXZ/Gou76UGa/XUTh4mWnWBAheokFOxMSBboXS66yquXGen85VPyictK2PRtCVa@fl/DpdHtYwt3p9rhs05o2zLvNUDIjAN2OCHRO16zTlfePp67tog5RFoL0EI6MitowxuYcutB3IcsfOKf42MUn3lY2w@b4Bg)
## Submission type
The submission defines appropriate functional interfaces for the input and output functions. The definitions of the interfaces aren't included in the byte count because they only provide type information and don't contribute any code to the solution. (In fact, both of them are general enough that they could well have been included in the set of functional interfaces in the standard library.) For more details see the TIO.
## Usage
Because the submission returns a function (instance of `C`), the output may be invoked directly (with `f`), but subsequent intermediate return values must be cast to an appropriate type before being invoked. Consult the TIO for a usage example.
Note that in Java functions (i.e. methods) are not first-class objects. Thus the syntax used in the output bullet of the challenge description is meaningless in Java. Rather than `f(a1, a2, a3)` we have `f.f(a1, a2, a3)`, and rather than `f(a1)(a2)(a3)` we have `f.f(a1).f(a2).f(a3)` (modulo typecasting).
## Limitations
When an intermediate result is applied (an argument added), the result is actually a mutated copy of the original result. This violates the spirit of currying, but meets the specific requirement stated in the challenge.
The form of input functions is limited by the decision to use functional interfaces, since a fully general functional interface has to use variadics or otherwise pack function parameters, and as a result the implementors of the interface must do so as well rather than listing parameters in the standard fashion. Technically this might disqualify the solution, since it is possible to support fully general non-variadic multi-parameter input functions by invoking them using reflection. My [solution using this strategy](https://tio.run/##dZHNjtMwEIDP8VOM9mQvrSXYG2mLUBACiRXSdm@Ig@M4qVvHjuxJl1Ll2YvjpAsCVrLG4/H8fDOzF0exdJ2y@@pw0W3nPMI@2niP2vDbnBBtUflaSAXF6mEDZ5I9QE2/lnslEYRvGODOu6cAj@MlSqNyMvwZtnUmJnMW1A9Utgok@12g7q0c//jHWVmRbPo2wjbcq9rEMvxe4c5Vi@vfC6GfY8lG@QUUG5LFcx5I5O/60mgJ0ogQ4F5oO7YQUGA0PqPJ3vsTrC/tctMtN1Y9QUHZ@YsOscX1@NyikAfK8jnb3P7zHDz7ewhnwUVVUc9yr7D3FgQP@qeibNW9w50Ob1uu7dEdFBULwdG9916cKGP5MFyyiH1FnLg/uUgSua/WOF0QXWdONGmLZCinS7LkmV3rwiso4RZkHo0DiYdkcxdzsqPTFbRxMnSLXtvm2/dxr@Hfxaa8L20HWlgnTp6QeaPwg4qqV9XkQG8S8U2inJz@r7KRtACvQm8wJk3L4VO7LZuVu@S1PQVULXc98i6io7GU0oJBElMCXtPXjEX5Jsk7NgYOZLj8Ag) (taking a `java.lang.reflect.Method` instead of an instance of a functional interface thanks to @user) is a bit longer, so I stick with this one.
## Ungolfed
```
f -> p -> new C() {
    List a = new Stack();
    public Object f(Object r) throws Throwable {
        a.add(r);
        return a.size() < p ? this : f.f(a.toArray());
    }
}
```
## Acknowledgments
* -211 bytes thanks to ideas from KrystosTheOverlord
[Answer]
# [Python 2](https://docs.python.org/2/), 78 bytes
```
c=lambda f,*a:f.func_code.co_argcount>len(a)and(lambda x:c(f,*a+(x,)))or f(*a)
```
[Try it online!](https://tio.run/##LctBCsMgEEDRvaeY5YyRQNOd0F4ljKO2hXQMopCe3qbQ3V/8t3/as@gyhtw2fofIkJ1ln@fcVVYpMc1SVq4PKV3bfUuKTKwR//fhBX9iwsMRUamQ0TKNmPJZ7IIT8gagptarAsMEASyIMXt9aYNTE14IF8IrjS8 "Python 2 – Try It Online")
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~42~~ 40 bytes
```
my&c={.count>1??{c(.assuming($^a))}!!$_}
```
[Try it online!](https://tio.run/##K0gtyjH7/z@3Ui3ZtlovOb80r8TO0N6@OllDL7G4uDQ3My9dQyUuUVOzVlFRJb4WqFBBLUPBViFZoxoorKCtoBKXpKAFJJNrNa25ihMrFTI0DDU1jDQ1jDWt/wMA "Perl 6 – Try It Online")
-2 bytes thanks to [Brad Gilbert b2gills](https://codegolf.stackexchange.com/users/1147/brad-gilbert-b2gills).
[Answer]
# [Haskell](https://www.haskell.org/), ~~211~~ ~~209~~ ~~189~~ 163 bytes
Flags:
```
-XMultiParamTypeClasses
-XFlexibleInstances
```
Actual code (119 bytes):
```
class C a b c where c::(a->b)->c
instance C()b b where c f=f()
instance C a b c=>C(d,a)b(d->c)where c a b=c(\d->a(b,d))
```
[Try it online!](https://tio.run/##bVBNS8NAEL3nV7yDh12aHNreAglIQCgoCnrwIMjsR5rFTVqyG2r/vHGSpqDoLm@HnXnz5jENhQ/r/ThqTyGgAkFB49TY3kLnuaCsVDIrdeK6EKnTFpWQikkLBXVRC/mjelEoykqYlKQShpvllcy1Qos3zpFQqZFybMl1yHPsHsEy86@AOSTAcYjPsb/vcIPQHE4c2vOtMRDrFGLD2DIkH@Z6G6GHvnfWcLsWM1POul1EVv4N/w64SqyxwTZJLvNYRHBD@vuVEtNdxBZnxAXF0Cne2RhbIax4HSvo8UvXnvZhzF4fBh/dE/XUvpyPtpoWb6f8nbefTnm7W3YZvgE)
The input type of the function to be curried is a nested tuple in a cons-like structure. The uncurried version of a function that adds 3 numbers together would look something like this, where it ends in an empty tuple.
```
myAdd :: (Int, (Int, (Int, ()) ) ) -> Int
myAdd (a, (b, (c, _))) = a + b + c
```
It works from the bottom up. There's an instance to curry a function of type `() -> r` that just applies the empty tuple to the function. Then there's another instance of `C` that can curry a function of type `(a,b)->c` if there is already an instance of `C` for `b -> c`.
Here's an `uncurr` function to accompany the currying function:
```
class Uncurry a b c d where
  uncurr :: (a->b)->c->d
instance Uncurry a r (a,()) r where
  uncurr f (a,()) = f a
instance Uncurry a b c d => Uncurry e (a->b) (e,c) d where
  uncurr f (e,c) =(uncurr(f e) c)
```
[Try it online!](https://tio.run/##zZNda4MwFIbv8ysOdBcJMxe1d4JCka0Uug/YejcYMUmpzNriB10Z@@3uRONMP9jF2MWUaPS85z2PJ3EtyjedZc0HH8Fiej9bTmc3cFdnVfooCrF5Pux0nImy1CWM@Cc5kt1m@j1NMj3Py0rk0krIRqQ5BAHMH4Cy7ikEtSUAu7p6qopFDldQrrd7vG0OU6WAjj2gPo4JDoYHajNdgayLItUK0yVtlaz1zSvg0fntYoHeYgw@TKxtnQ/GtHvodX0Nin6eczFQQxmHzTdwjuMv@XwLSLqG9ATHV0Qwp3WzrRMYSHBID14NZAgCriHBIQkZvupHMEcmMFWemJj1h9iGFOzXutAgg4AKHiWMR5JHiqR2E0CMSIiatHqrNfNQICcGHOW3ZRjFVHsCkzQ1bszNk/RF8chkK8wmTcezbFt@OKbCFtv1NB108YaqQ2IBHSpOTrJXfSTEqbiY3IN/v9K2IOCXSHZOtLKB0G45ugLNQLLmH/8vf7odmy8)
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 5 bytes
Good ol' Mathematica built-ins
```
Curry
```
Takes 2 arguments, the function and the number of arguments.
[Try it online!](https://tio.run/##TY29CsJAEIT7PMWAnZ7kvzAhlS9gvyxh70dMESPHCfr05xkRMrDbzHwzs4SbmyVMRqJ5ej/Ec/rveF0WklFBpzMjoxsgOEBjD9NnWvzGVbD/xPGXQA7bZxc/3QN9WynVKdRMLVPFVDNj1Q7u9XAmONuhLLdAWlBomMqiYGpWqk3UFmhOVd5m8QM "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [Julia 1.0](http://julialang.org/), 40 bytes
```
f>n=n<2 ? f : ((x...)->y->f(x...,y))>n-1
```
[Try it online!](https://tio.run/##LYkxDgIxDAT7vGJLWzjROdchzvAVGh8gFAqESO7zuQhRrDQz@/g871etvbuVpZwyznAcQVRTShytRfMfS2O2ErU7FlCVJhsjGupBpzY2bWEdj9scwuV9e33hpJJl5r@upEyZaYS@Aw "Julia 1.0 – Try It Online")
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), ~~58~~ 57 bytes
```
∇r←(a f g)x
:If a[1]=≢a
r←g 1↓a,x
:Else
r←(a,x)f g
:End
∇
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v//UUd70aO2CRqJCmkK6ZoVXFaeaQqJ0Yaxto86FyVygaTSFQwftU1O1AHKueYUp3JBlOtUaAI1AIXyUriAZvx/1DdVASihoKGhYaxgDDSs@lFXk7b@o96ttZoKhgqaRpr/AQ "APL (Dyalog Classic) – Try It Online")
Calling syntax (with curried function `g`, arguments `x1` through `x3`, and number of arguments `n`):
`((n x1 f g) x2) x3`
Requires `⎕IO←1`
[Answer]
# [Julia 0.6](http://julialang.org/), 48 bytes
```
c=(f,n,a=[])->n>1?x->c(f,n-1,[a;x]):x->f(a...,x)
```
[Try it online!](https://tio.run/##TYy9CsJAEIT7e4r1SLGrm4C/iJIIVpY2VmKxuURzcjklKOTt4x1aWAyzM8s397ezshpgMDle2bPk5wulhS@muz4tTOzSKZ9l219oE5orSpZl3NNgxBkULtkQ5CAwgRLGYNQtJIPxyzAn9eysfzmPN5wRLgnXREo19ktyFVl9qJ17MCQSVAYFUnwFCVY00r/BxjIs/uf0QTqrCfWplWjHrm6j75s6HqSGDw "Julia 0.6 – Try It Online")
Port of @EricTheOutgolfer's Python answer. 
[Answer]
**Java 8... Using lambda insanity, 152 bytes**
Ok so I know that there is already a java 8 answer, but I wanted to use one using almost entirely lambdas without the use of java's Function<> class.
Here is the functional interface for the lambda expressions
```
interface K{Object f(int...x);}
```
And here is the actual expression
```
a->a.length==2?(K)c->a[0]+a[1]*c[0]:a.length==3?a[0]+a[1]*a[2]:(K)b->(b.length == 1)?(K)c->a[0]+b[0]*c[0]:a[0]+b[0]*b[1];
```
Yeah, so I know this looks really crazy, but the latter is mainly just using ternary operators to distinguish different number of arguments to what needs to be returned.
Given the submitted function
```
K function = a->a.length==2?(K)c->a[0]+a[1]*c[0]:a.length==3?a[0]+a[1]*a[2]:(K)b->(b.length == 1)?(K)c->a[0]+b[0]*c[0]:a[0]+b[0]*b[1];
```
`function(a, b, c)` is `function.f(a, b, c)`, `function(a)(b)(c)` is `((K)((K)function.f(a)).f(b)).f(c)`
Basically any situation that results in a curried result, the answer must be cast to `(K)` so then it can have a function called on it, otherwise the result is an integer. You can even do the following! `(function(a))(a,b)` which would be `((K)function.f(a)).f(b,c)` etc...
This probably took me way too long, and we already have a java 8 answer, but I feel like it is still an interesting way to go about it.
[Answer]
**[Lispy](https://github.com/andrakis/node-lispy), 169 bytes**
```
(define f(lambda A(begin(define G(lambda(X)(if(>=(length X)C)(proc:apply(head A)X)(lambda Args(G(concat X Args))))))(define C(length(lambda:args(head A))))(G(tail A)))))
```
Implements the [generic abritrary ES5 currying algorithm](https://rosettacode.org/wiki/Currying#Generic_currying) on Rosetta Code.
Ungolfed and test:
```
(begin
;; f is a lambda that captures all arguments
(define f (lambda Arguments (begin            ;; function extraCurry(f) {
    (define F (head Arguments))
    (define A (tail Arguments))
    (define _curry (lambda (XS)               ;; function _curry(xs) {
        (if (>= (length XS) intArgs)          ;; xs.length >= intArgs ?
            (proc:apply F XS)                 ;;   f.apply(null, xs)
            (lambda Args                      ;; : function() {
                (_curry (concat XS Args)))    ;; return _curry(xs.concat([].slice.apply(arguments)))
        )
    ))
    (define intArgs (length (lambda:args F))) ;; intArgs = f.length
    (_curry A)                                ;; return _curry([].slice.call(arguments, 1))
)))
(define product3 (lambda (a b c) (* a b c)))
;; [14, 28, 42, 56, 70, 84, 98, 112, 126, 140]
(print (map [1 2 3 4 5 6 7 8 9 10] (((f product3) 7) 2))))
```
Try online link coming soon.
[Answer]
# Dotty, ~~345~~ ... ~~221~~ 186 bytes
```
def>[F,T,X](f:F)(using? :F TupledFunction T,e:T=>X)=e(?tupled f)
given[A]as((EmptyTuple=>A)=>A)=_(Tuple())
given[A<:Tuple,B,C,D](using t:(A=>B)=>C)as((D*:A=>B)=>D=>C)=f=>h=>t(c=>f(h*:c))
```
[Try it in Scastie](https://scastie.scala-lang.org/YZMS7304S8e11GAlA9N0RQ)
**This will not work in Scala 3.0 as `TupledFunction` will be [removed](https://github.com/lampepfl/dotty/commit/f4e1ca4f565c74fbe1aa56ea88ce6f59409ccdf0).** However, it may be added back later.
This one doesn't do any unsafe casting or other trickery.
`>` is the method to call. The type parameters `F`, `T`, and `X` represent the type of the input function, the type of the input function if it took a single tuple instead of multiple arguments, and the type of the resulting curried function, respectively. The first parameter, `f`, is the function to be curried. There are also two implicit parameters, `?` and `e`. `?` is a `TupledFunction` object that can convert between `F` and `T`, i.e., tuple and untuple a function. It is provided in the standard library automatically, and makes it easier for `e` to do its work.
`e` operates on the tupled form of `f`. There's a base implicit function that takes an a function `EmptyTuple=>A` and returns an `A` by just passing an empty tuple to that function. Another `given` builds on top of that by deconstructing `f` into `D *: A => B` (`D` is the type of the first parameter of `f`, `A` is the type of the rest of the parameters as a tuple, and `B` is the type of `f`'s result). It uses another implicit function of type `(A => B) => C`, where `C` is the curried version of `A => B`. This second case returns a function taking a `D` and then applying `t` to a new function where the `D` from before is cons-ed to an `A` before applying `f` to it.
## Dotty, 144 bytes
```
def a[T](x:Any)=x.asInstanceOf[T]
def c[T,R](f:T=>R,n:Int):Any=>Any=h=>a(n match{case 1=>f(a(Tuple1(h)))case _=>c(t=>f(a(h*:a[Tuple](t))),n-1)})
```
[Try it in Scastie](https://scastie.scala-lang.org/3QJTPxrITk2tA0A2xns7Jw)
Requires function to be tupled beforehand.
[Answer]
# [Factor](https://factorcode.org/), 6 bytes
```
ncurry
```
[Try it online!](https://tio.run/##BcExDkBAEAXQ3il@TSJBxwFEoxGVKCabwcYaMkbB5dd7Czk7NY5D17c1VhZWCv4j86fc2FmFAw6yDZey2XupF0OTJAVKVJiQIsOMMop7VN@Y33CBSeMP "Factor – Try It Online")
Builtin.
A non-trivial implementation might be:
```
[ [ curry ] times ]
```
Currying is a pretty uncomplicated affair in a concatenative language. :)
[Answer]
# [Ruby](https://www.ruby-lang.org/), 12 bytes
Ruby has a built-in method `curry` which can be called on a lambda that gives the desired behavior. The below code returns a lambda that calls `curry` on its argument.
```
proc &:curry
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72kqDSpcsEiN9ulpSVpuhZrCorykxXUrJJLi4oqIUI3ddMVbBV07RJ1knSSqxUStZO0khVqubjS44HCbtHpsVxcBQrp8dGGOkax0caxEE0LFkBoAA)
]