n-ary curry в CoffeeScript

Я играл с CoffeeScript, когда обнаружил, что пишу следующие строки, а затем смотрю на них с трепетом:

compose = (f, g) -> (x) -> f g x
curry = (f) -> (x) -> (y) -> f(x, y)
uncurry = (f) -> (x, y) -> (f x) y

Как приятно, я подумал! Теперь, в качестве упражнения, я подумал, что обобщу функции карри и uncurry до n args, чтобы получить что-то похожее на это:

curry2 = (f) -> (x) -> (y) -> f(x, y)
curry3 = (f) -> (x) -> (y) -> (z) -> f(x, y, z)
curry4 = (f) -> (x) -> (y) -> (z) -> (t) -> f(x, y, z, t)

И то же самое для uncurry:

uncurry2 =  (f) -> (x, y) -> (f x) y
uncurry3 = (f) -> (x, y, z) -> ((f x) y) z
uncurry4 = (f) -> (x, y, z, t) -> (((f x) y) z) t

Написать n-ary uncurry было не очень сложно:

uncurry = (n) -> (f) -> (args...) ->
    if n == 1
        f args[0]
    else
        ((uncurry n - 1) f args.shift()) args...

С другой стороны, я не могу понять, как заставить n-ary curry работать. Я думал о реализации сначала функции curry_list, которая является обобщением этого набора:

curry_list2 = (f) -> (x) -> [x, y]
curry_list3 = (f) -> (x) -> (z) -> [x, y, z]
curry_list4 = (f) -> (x) -> (z) -> (t) -> [x, y, z, t]

Вот реализация:

curry_list = (n) ->
    curry_list_accum = (n, accum) ->
        if n
            (x) ->
                accum.push x
                curry_list_accum n - 1, accum
        else
            accum
    curry_list_accum n, []

А затем я бы просто сочинил curry_list с приложением функции для получения карри. Это то, что я пытался сделать:

curry = (n) ->
    apply_helper = (f) -> (args) -> f args...
    (f) -> compose (apply_helper f), (curry_list n)

Но по какой-то причине это не работает. Для примера:Попытка оценить

curry(3)((a,b,c) -> a + b + c)(1)(2)(3)

приводит к следующей ошибке:

Function.prototype.apply: Список аргументов имеет неправильный тип

Теперь, после записи еще нескольких заметок, я понимаю, что попытка составить f с curry_list некорректна. У меня есть интуиция, что то, что я ищу, это то, что выглядит как эта композиция, но не совсем это. Правильно ли я думаю, что это так?

Наконец, что было бы правильным внедрением?

16
задан HaskellElephant 5 December 2011 в 11:12
поделиться