Scheme:使用抽象列表函数而不使用递归

Scheme:使用抽象列表函数而不使用递归,scheme,Scheme,我如何使用抽象列表函数(foldr,foldl,map,和过滤器)编写函数,而不使用递归,递归消耗一个数字列表(列表a1 a2 a3…),并生成交替和a1-a2+a3…?以下是一个可能的解决方案: (define (sum-abstract-list-functions lst) (car (foldl (lambda (e acc) (cons (+ (car acc) (* e (cdr acc))) (- (cdr acc))))

我如何使用抽象列表函数(
foldr
foldl
map
,和
过滤器
)编写函数,而不使用递归,递归消耗一个数字列表
(列表a1 a2 a3…
),并生成交替和
a1-a2+a3…

以下是一个可能的解决方案:

(define (sum-abstract-list-functions lst)
  (car
   (foldl
    (lambda (e acc)
      (cons (+ (car acc) (* e (cdr acc)))
            (- (cdr acc))))
    '(0 . 1)
    lst)))
我只使用了
foldl
cons
car
cdr
。诀窍?累加两个值:实际总和(在累加器的
car
部分)和当前符号(+/-1在累加器的
cdr
部分)。累加器在0中初始化为和,在+1中初始化为符号,最后我返回和,累加器的
car
部分。像这样使用它:

(sum-abstract-list-functions (list 1 2 3 4 5))
> 3
编辑:

如前所述,此解决方案是所有解决方案中最简单的:

(define (sum-abstract-list-functions lst)
  (foldr - 0 lst))

这是家庭作业吗?我们可以把这个问题分成两个子问题:

  • 取一个列表
    (a1a2a3a4…a2n-1a2n)
    并交替地对其中的元素求反,以生成
    (a1(-a2)a3(-a4)…a2n-1(-a2n))
  • 对结果列表中的元素求和
第二部分是琐碎的一部分:

(define (sum xs)
  (foldl + 0 xs))
第一个比较难,但也不难。您需要转换列表,同时保持一个布尔状态,该状态指示您检查的是偶数还是奇数元素,并相应地求反。我可以看到三种方法:

  • 变异方式:将状态放入传递给
    映射的闭包中。然后,闭包从一个调用修改其环境到下一个调用
  • 在折叠结果中保留状态:折叠结果是一对,包含“真实”结果和作为元素的状态
  • 使用不同种类的抽象列表函数
下面是第三种方法的一个例子(如果这是家庭作业,我打赌你的老师可能会怀疑你想出了这个方法):

这里有一个提示:

a1 - a2 + a3 - a4 ... aN

a1 - (a2 - (a3 - (a4 - ... (aN - 0) ...)))
现在怎么解决这个问题是显而易见的吗

a1 - (a2 - (a3 - (a4 - ... (aN - 0) ...)))