2017-03-05 43 views
0

compose功能首先應用最後一個功能,即它以相反的順序應用發送的功能。例如:反轉撰寫功能中的功能用法

((compose sqrt add1) 8) 

上面會ADD1到8,然後找到SQRT 9.

欲因此創建該第二個第一施加第一發送功能,並且然後,一個mycompose功能第三等,在上面的例子中,首先應用sqrt,然後add1。我可以管理以下:

(define (mycompose L arg) 
    (let loop ((L L) 
      (res arg)) 
    (cond 
     [(empty? L) res] 
     [else (loop (rest L) ((car L) res))]))) 

(mycompose (list sqrt add1) 8) 

我相信有更好的方法。尤其是,上面可以使用宏來實現,並且允許多個參數輪流發送給每個函數。

+2

你可以用'(define(mycompose.fs)(apply compose(reverse fs))'來實現你的函數,它可以滿足你所有的需求而不需要宏。 –

+0

我知道有一個更好的方法。謝謝。 – rnso

回答

3

你描述的這個「反向構圖」通常被稱爲鵝口瘡the point-free package provides a thrush function,它完全符合你的想法。但是,假設您想自己實現它。那麼,最簡​​單的方法是重用現有的實施compose,因爲thrush只是compose並反轉參數:

(define (thrush . fs) 
    (apply compose (reverse fs)) 

這,其實,如何自由點包實現thrush。不過,這可能不令您滿意,因爲您不知道compose是如何實現的。好了,幸運的是,我們可以從頭開始實現thrush用一個簡單的褶皺:

(define (thrush . fs) 
    (for/fold ([f values]) 
      ([g (in-list fs)]) 
    (λ args (call-with-values (thunk (apply f args)) g)))) 

這裏真正的技巧是使用call-with-values,這妥善處理返回多個值的功能。就像Racket的compose一樣,它會接受多個值,並將它們作爲多個參數傳遞給管道中的函數,從而在函數輸入和函數輸出之間創建一個很好的對稱性。

+0

感謝您的明確解釋。 – rnso