nam*_*ked 8 scheme list racket
下面是我的代码,它将列表的car元素(carVal)
和列表(初始化为空)作为参数.我想将元素追加到列表中,但同样不起作用.
(define populateValues
(lambda (carVal currVal)
(append currVal(list carVal ))
(display currVal)))
Run Code Online (Sandbox Code Playgroud)
显示屏始终显示空列表()
.谁能帮我理解为什么?
Zor*_*orf 25
好吧,有append!
一个原始的,它解决了你的大多数问题,正如已经指出的,Scheme倾向于对变异皱眉,它是可能的,但通常是避免的,所以变异的所有程序!
在它们的末尾都有一个(称为爆炸).
此外,set!
不改变数据,它改变一个环境,它使变量指向另一个东西,原始数据保持不变.
Scheme中的变异数据非常繁琐,但是,给你我自己的追加实现!看看它是如何完成的:
(define (append! lst . lsts)
(if (not (null? lsts))
(if (null? (cdr lst))
(begin
(set-cdr! lst (car lsts))
(apply append! (car lsts) (cdr lsts)))
(apply append! (cdr lst) lsts))))
Run Code Online (Sandbox Code Playgroud)
注意使用set-cdr!
,这是一个真正的mutator,它只适用于对,它会改变内存中的数据,不像`set!'.如果一对传递给一个函数并用set-cdr进行变异!或者set-car !,它会在程序中的每个位置发生变异.
这服从SRFI追加!例如,声明它应该是可变参数并且应该返回未定义的值.
(define l1 (list 1 2 3 4))
(define l2 (list 2 3 4))
(define l3 (list 3 1))
(append! l1 l2 l3)
l1
l2
l3
Run Code Online (Sandbox Code Playgroud)
哪个显示:
(1 2 3 4 2 3 4 3 1)
(2 3 4 3 1)
(3 1)
Run Code Online (Sandbox Code Playgroud)
如可见,追加!可以采用无数个参数,除了最后一个,它都会变异.
虽然Scheme可能不是你理想的语言.使用追加!如前所述是非标准的,相反,append是首选的,它不会发生变异并被称为其返回值.我这样实现的:
(define (append . lsts)
(cond
((null? lsts) '())
((null? (car lsts)) (apply append (cdr lsts)))
(else (cons (caar lsts) (apply append (cdar lsts) (cdr lsts))))))
> (append (list 1 2 3) (list 4 5 6) (list 'granny 'porn))
(1 2 3 4 5 6 granny porn)
Run Code Online (Sandbox Code Playgroud)
在没有突变,大量使用递归和不使用测序的情况下,这显示了更熟悉的Scheme样式.
编辑:如果您只想将一些元素添加到列表中而不是本身加入两个:
(define (extend l . xs)
(if (null? l)
xs
(cons (car l) (apply extend (cdr l) xs))))
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(extend '(0 1 2 3) 4 5 6)
(define list1 '(0 1 2 3))
(extend! list1 4 5 6)
list1
Run Code Online (Sandbox Code Playgroud)
这符合您的期望