2015-11-05 37 views
2

對於具有三個或更多參數的函數,currying如何工作?用n(3個或更多)參數來捲曲函數?

我搜索了SO和Google。例如,具體例子What is 'Currying'?; https://en.wikipedia.org/wiki/Currying是關於二進制函數f (x, y)

在這種情況下,g = curry f取一個參數併產生一個一元函數(f x)

我的問題是:

我們如何始終如一地擴展,以一個正參數的函數,例如f3 (x,y,z)? (F3:X-> Y-> Z-> U)

如果curry操作被作爲一個高階函數處理,所以不能直接適用於f3,因爲curry預計(X,Y) -> Z類型的函數,並且f3的論點是一個三元組,而不是一對。使用n元組的函數fn也會出現同樣的問題。

一個解決方案可能是(x,y,z)(x,(y,z)),然後curry似乎適用。然後curry f3 = (f3 x)(Y,Z) -> U的類型。但是咖喱應該是這樣嗎?

+6

您可能喜歡的元組包,特別是['Data.Tuple.Curry'](HTTP:/ /hackage.haskell.org/package/tuple-0.3.0.2/docs/Data-Tuple-Curry.html)。如果你的回答是「GROSS!」,那麼你並不孤單。 –

+0

@DanielWagner我笑了。有時我希望元組被定義爲'T a1(T a2 ..))',其中'T a b = T a!b'可能帶有一些特別的優化來恢復良好的性能。 – chi

+0

球拍的實施很有趣:http://docs.racket-lang.org/reference/procedures.html?q=curry#%28def._%28%28lib._racket%2Ffunction..rkt%29._curry%29% 29 – uselpa

回答

1

如果咖喱操作被視爲高階函數,它不能直接應用到f3,因爲咖喱需要(X,Y) - > Z類型的函數,並且f3的參數是三倍,而不是一對。採用n元組的函數fn也會出現同樣的問題。

您的問題的某些方面包括許多Haskell的強類型,這些類型在大多數Lisps中都不存在。例如,一個簡單的n進制咖喱可以定義爲:

(defun curry (function first-argument) 
    (lambda (&rest args) 
    (apply function first-argument args))) 

CL-USER> (let ((f (curry (curry (lambda (x y z) 
            (* x (+ y z))) 
           2) 
         3))) 
      (mapcar f '(1 2 3 4 5))) 
; (8 10 12 14 16)