(define wadd (lambda (i L)
(if (null? L) 0
(+ i (car L)))
(set! i (+ i (car L)))
(set! L (cdr L))))
(wadd 9 '(1 2 3))
这不会返回任何内容。我希望它可以(3 + (2 + (9 + 1))
,它应该等同于15
。我是否以错误的方式使用set!
?我是否可以在set!
条件下致电if
?
答案 0 :(得分:3)
我从你的代码中推断出你打算以某种方式遍历列表,但wadd
过程中没有任何内容迭代列表 - 没有递归调用,没有循环指令,没有:只是一个误用的条件和一个一对set!
只能执行一次。我不会尝试修复问题中的程序,无法修复 - 我宁愿向您展示解决问题的正确方法。你想要这些方面的东西:
(define wadd
(lambda (i L)
(let loop ((L L)
(acc i))
(if (null? L)
acc
(loop (cdr L) (+ (car L) acc))))))
执行时,上一个过程将评估此表达式:(wadd 9 '(1 2 3))
,如下所示:
(+ 3 (+ 2 (+ 1 9)))
。请注意,正如@Maxwell指出的那样,使用foldl可以更简洁地表达上述操作:
(define wadd
(lambda (i L)
(foldl + i L)))
作为一般规则,在Scheme中,你不会像在命令式C语言中那样频繁地使用赋值(set!
指令) - 首选函数式编程风格,它依赖于关于不会改变状态的递归和操作。
答案 1 :(得分:2)
我认为如果你修复了缩进,你的问题就会变得更加明显。
函数set!
返回<#void>
(或类似虚无的东西)。你的lambda wadd
做了以下事情:
L
是否为空,评估为0或i
+ (car L)
,然后丢弃结果。i
并评估为L
并且不返回任何内容如果在lambda中放置多个语句,它们将明确地包含在begin
语句中:
(lambda () 1 2 3) => (lambda () (begin 1 2 3))
在序列中多个表达式的begin
语句中,整个begin
求值为最后一个语句的结果:
(begin 1 2 3) => 3