我目前正在学习 R5RS 方案(来自 PocketScheme),我发现我可以使用内置于方案的某些变体(但不是全部)中的函数:Append!
换句话说 - 破坏性地改变列表。
我对实际代码并不感兴趣,而是对答案感兴趣,而是对将列表作为函数(或向量或字符串)传递然后对其进行变异的过程感兴趣。
例子:
(define (append! lst var)
(cons (lst var))
)
当我使用上述方法时,我必须做类似的事情(define list (append! foo (bar))
我想要一些更通用的东西。
尽管允许突变,但在Scheme 中强烈建议不要进行突变。 PLT 甚至删除了set-car!
and set-cdr!
(尽管他们将它们“替换”为set-mcar!
and set-mcdr!
)。然而,一个规范append!
出现在SRFI-1 http://srfi.schemers.org/srfi-1/srfi-1.html#append!. This append!
与你的有点不同。在 SRFI 中,实施may,但不是required修改 cons 单元格以附加列表。
如果你想拥有一个append!
那是保证要更改要附加的列表的结构,您可能必须自己编写。这并不难:
(define (my-append! a b)
(if (null? (cdr a))
(set-cdr! a b)
(my-append! (cdr a) b)))
为了保持定义简单,这里没有错误检查,但很明显,您需要传入一个长度至少为 1 的列表,如下所示a
,以及(最好)一个(任意长度的)列表b
。原因a
长度必须至少为 1 因为你不能set-cdr!
在一个空列表上。
既然您对它的工作原理感兴趣,我会看看是否可以解释一下。基本上,我们要做的就是沿着列表向下走a
直到我们到达最后cons
对,即(<last element> . null)
。所以我们首先看看是否a
通过检查已经是列表中的最后一个元素null
in the cdr
。如果是的话,我们使用set-cdr!
将其设置到我们要附加的列表中,然后就完成了。如果没有,我们必须打电话my-append!
on the cdr
of a
。每次我们这样做,我们就离结局更近了a
。由于这是一个变异操作,我们不会返回任何内容,因此我们不需要担心将修改后的列表形成为返回值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)