2016-10-12 34 views
1

我一直在試圖將一個正常的函數轉換成一個更高階的函數來做同樣的事情。該函數應該將運算符作爲參數,然後將該運算符應用於列表中的每個元素。例如,如果我選擇運算符「+」,它會返回列表中所有元素的總和。方案 - 如何循環匿名函數?

的功能正常版本:

(define (accumulate proc id lst) 
    (cond ((null? lst) id) 
    ((eqv? (cdr lst) '()) (car lst)) 
    (else (proc (car lst) (accumulate proc id (cdr lst)))))) 

更高的功能順序版本(不完全):

(define (acc-proc proc id) 
(lambda (lst) 
(cond ((null? lst) id) 
     ((null? (cdr lst)) (car lst)) 
     (else 

在正常功能我使用的是遞歸調用循環,但我不能循環更高階的函數,因爲它沒有lst作爲參數。相反,參數lst在匿名lambda過程中。

我是新來的計劃,所以原諒我,如果我的解決方案是不好的。也許有沒有更好的方式做到這一點沒有循環?我不知道該怎麼把成else語句...

回答

1

注意,有一個在你的原始功能的錯誤:你的第二個情況是指你的除了空列表都忽略id

> (accumulate + 34 '(1 2 3)) 
6 
> (accumulate + 34 '()) 
34 

您只需要兩種情況;空列表和非空列表。

對於實際的問題:如果「匿名」的部分不是必需的,你可以使用本地命名函數:

(define (acc-proc proc id) 
    (define (recurse lst) 
    (if (null? lst) 
     id 
     (proc (car lst) (recurse (cdr lst))))) 
    recurse) 

如果anonymousity是很重要的,你需要採取的演算路線和使用一個定點組合器。

+0

這不是一個錯誤。第二種情況應該忽略該ID。如果列表爲空,它將返回id。 – Schytheron

+0

(accumulate + 0'()) – Schytheron

+0

@Schytheron是的,但是'(accumulate + 34'(1 2 3))'應該是40,而不是6.'id'是所有列表的「起點」,而不僅僅是空的一個。 – molbdnilo