2016-10-12 50 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