附加!在计划? [英] Append! in Scheme?
问题描述
我学习R5RS计划的时刻(从PocketScheme),我发现我可以用内置于计划的一些变体,但功能不是所有:追加
I'm learning R5RS Scheme at the moment (from PocketScheme) and I find that I could use a function that is built into some variants of Scheme but not all: Append!
在换句话说 - 破坏性改变列表
In other words - destructively changing a list.
我没有那么在实际的code多大兴趣作为一个答案一样多理解由哪一个可以传递列表作为一个函数(或向量或字符串),然后发生变异,它的进程。
I am not so much interested in the actual code as an answer as much as understanding the process by which one could pass a list as a function (or a vector or string) and then mutate it.
例如:
(定义(追加!LST VAR)
(缺点(LST VAR))
)
(define (append! lst var) (cons (lst var)) )
当我使用的方法如上,我要像做(定义列表(追加!富(巴)),我想更多的东西通用的。
When I use the approach as above, I have to do something like (define list (append! foo (bar)) which I would like something more generic.
推荐答案
突变,虽然允许,强烈方案劝阻。 PLT甚至只要删除设置车!
和设置CDR!
(尽管他们替换成他们去了与设置MCAR!
和设置MCDR!
)。然而,对于一个规范追加!
中出现的 SRFI-1 。这追加!
是比你有点不同。在SRFI,实施的可以的,但不是的需要的修改利弊细胞追加名单。
Mutation, though allowed, is strongly discouraged in Scheme. PLT even went so far as to remove set-car!
and set-cdr!
(though they "replaced" them with set-mcar!
and set-mcdr!
). However, a spec for append!
appeared in SRFI-1. This append!
is a little different than yours. In the SRFI, the implementation may, but is not required to modify the cons cells to append the lists.
如果你想有一个追加!
是的保证的更改是附加在列表的结构,你可能会必须把它写自己。这并不难:
If you want to have an append!
that is guaranteed to change the structure of the list that's being appended to, you'll probably have to write it yourself. It's not hard:
(define (my-append! a b)
(if (null? (cdr a))
(set-cdr! a b)
(my-append! (cdr a) b)))
要保持清晰简单,没有任何错误检查这里,但很明显,你将需要在长度至少为1的列表,通过为 A
,和(preferably)(任意长度的)列表作为 b
。究其原因 A
必须至少长1是因为你不能设置CDR!
一个空的名单上。
To keep the definition simple, there is no error checking here, but it's clear that you will need to pass in a list of length at least 1 as a
, and (preferably) a list (of any length) as b
. The reason a
must be at least length 1 is because you can't set-cdr!
on an empty list.
既然你感兴趣的是如何工作的,我会看看我能不能解释一下。基本上,我们想要做的是沿着列表 A
,直到我们到达最后劣势
对,这是(小于最后一个元素方式>空)
。所以,我们先看看 A
已经由<$ C $检查空
在列表中的最后一个元素C> CDR 。如果是,我们使用设置CDR!
将其设置为我们追加列表,我们就大功告成了。如果没有,我们得叫我-追加!
上的
。每次我们这样做的时候,我们更接近年底 CDR
A A
。由于这是一个变异操作,我们不会返回任何东西,所以我们并不需要担心形成修改后的列表作为返回值。
Since you're interested in how this works, I'll see if I can explain. Basically, what we want to do is go down the list a
until we get to the last cons
pair, which is (<last element> . null)
. So we first see if a
is already the last element in the list by checking for null
in the cdr
. If it is, we use set-cdr!
to set it to the list we're appending, and we're done. If not, we have to call my-append!
on the cdr
of a
. Each time we do this we get closer to the end of a
. Since this is a mutation operation, we're not going to return anything, so we don't need to worry about forming our modified list as the return value.
这篇关于附加!在计划?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!