title: n-ary curry in CoffeeScript
body: <p>I was playing with CoffeeScript when I found myself writing the following lines and then looking at them in awe:</p>
  
  <pre><code>compose = (f, g) -&gt; (x) -&gt; f g x
  curry = (f) -&gt; (x) -&gt; (y) -&gt; f(x, y)
  uncurry = (f) -&gt; (x, y) -&gt; (f x) y
  </code></pre>
  
  <p>How nice, did I think! Now, as an exercise, I thought I would generalize the curry and uncurry functions to n args, to obtain something similar to this:</p>
  
  <pre><code>curry2 = (f) -&gt; (x) -&gt; (y) -&gt; f(x, y)
  curry3 = (f) -&gt; (x) -&gt; (y) -&gt; (z) -&gt; f(x, y, z)
  curry4 = (f) -&gt; (x) -&gt; (y) -&gt; (z) -&gt; (t) -&gt; f(x, y, z, t)
  </code></pre>
  
  <p>And the same thing for uncurry:</p>
  
  <pre><code>uncurry2 =  (f) -&gt; (x, y) -&gt; (f x) y
  uncurry3 = (f) -&gt; (x, y, z) -&gt; ((f x) y) z
  uncurry4 = (f) -&gt; (x, y, z, t) -&gt; (((f x) y) z) t
  </code></pre>
  
  <p>Writing the n-ary uncurry was not very hard:</p>
  
  <pre><code>uncurry = (n) -&gt; (f) -&gt; (args...) -&gt;
      if n == 1
          f args[0]
      else
          ((uncurry n - 1) f args.shift()) args...
  </code></pre>
  
  <p>On the other hand, I can't figure out how to get the n-ary curry to work. I thought of implementing first a curry_list function that is the generalization of this suite:</p>
  
  <pre><code>curry_list2 = (f) -&gt; (x) -&gt; [x, y]
  curry_list3 = (f) -&gt; (x) -&gt; (z) -&gt; [x, y, z]
  curry_list4 = (f) -&gt; (x) -&gt; (z) -&gt; (t) -&gt; [x, y, z, t]
  </code></pre>
  
  <p>Here's the implementation:</p>
  
  <pre><code>curry_list = (n) -&gt;
      curry_list_accum = (n, accum) -&gt;
          if n
              (x) -&gt;
                  accum.push x
                  curry_list_accum n - 1, accum
          else
              accum
      curry_list_accum n, []
  </code></pre>
  
  <p>And then I would just compose curry_list with function application to obtain currying. That's what I tried to do:</p>
  
  <pre><code>curry = (n) -&gt;
      apply_helper = (f) -&gt; (args) -&gt; f args...
      (f) -&gt; compose (apply_helper f), (curry_list n)
  </code></pre>
  
  <p>But for some reason, it does not work. For exemple, trying to evaluate</p>
  
  <pre><code>curry(3)((a,b,c) -&gt; a + b + c)(1)(2)(3)
  </code></pre>
  
  <p>yields the following error:</p>
  
  <blockquote>
    <p>Function.prototype.apply: Arguments list has wrong type</p>
  </blockquote>
  
  <p>Now after jotting some more notes I understand that trying to compose f with curry_list is incorrect. I do have the intuition that what I'm looking for is something that looks like this composition, but is not exactly that. Am I correct in thinking that?</p>
  
  <p>Finally, what would be a correct implementation?</p>