我想你可能想稍微概括一下,所以我制作了filter-sum,这样你就可以做到这一点:
#!r7rs ; #!r6rs for r6rs
(import (scheme) ; replace scheme with rnrs for r6rs
(only (srfi :1) filter fold)) ; remove filter for r6rs
;; I renamed you list
(define *lista-de-elemente* '(2 4 8 10 12 14 16))
(define (suma)
(define (>10? x)
(> x 10))
(filter-sum >10? *lista-de-elemente*))
(suma) ; ==> 42
以下是filter-sum 的一些可能版本。
我们有直接的递归方式:
(define (filter-sum predicate lst)
(cond ((null? lst) 0)
((not (predicate (car lst))) (filter-sum predicate (cdr lst)))
(else (+ (car lst) (filter-sum predicate (cdr lst))))))
但这不是很好,因为顺序或数字并不重要。我们可以使用累加器递归地执行此尾部操作,这里使用命名为 let 而不是腋下过程:
(define (filter-sum predicate lst)
(let loop ((lst lst)(acc 0))
(if (null? lst)
acc
(loop (cdr lst)
(if (predicate (car lst))
(+ acc (car lst))
acc)))))
现在这种带有尾递归和累加器的循环可以转换为折叠。你在SRFI-1 list library中找到折叠:
(define (filter-sum predicate lst)
(fold (lambda (x acc)
(if (predicate x)
(+ acc x)
acc))
0
lst))
现在的大部分代码是是否应该添加。使用filter,您可以过滤掉,以便添加折叠中的每个元素:
(define (filter-sum predicate lst)
(fold + 0 (filter predicate lst)))
filter 也在 SRFI-1 列表库中。现在,如果您知道 10 以上的数字列表很短.. 就像几百个一样,您可以完全将 fold 更改为 apply,它甚至可能会变得更快一些,但是您正在限制列表。 (许多方案系统将参数推送到有限大小的堆栈上,而折叠将同时累积列表中的一个元素。)