您的代码不使用任何类型的循环。为了获得所有的事件,你必须以某种方式迭代。
在方案中,这通常通过递归使用named let
来完成。在每次迭代期间,您都有一个索引变量i
,结果列表r
和其余输入列表L
,在每个迭代步骤中该列表变小。
您示例中的if
子句可以简化。
如果您在列表的第一个元素中找到值,则增加索引,将当前索引附加到结果列表并继续输入列表的其余部分。
如果您没有匹配,那么请增加索引,但不要将索引添加到结果列表中,并继续使用剩余的输入列表。
当L
为空时,您已到达输入列表的末尾。在这种情况下返回结果列表。您必须翻转结果列表,因为cons
会在开始处追加。
(define positions
(lambda (A L)
(let loop ((i 0)
(r '())
(L L))
(if (null? L)
(reverse r)
(if (eq? (car L) A)
(loop (+ i 1) (cons i r) (cdr L))
(loop (+ i 1) r (cdr L)))))))
通过将if子句放入循环的参数中,可以避免输入两次循环命令。
(define positions
(lambda (A L)
(let loop ((i 0)
(r '())
(L L))
(if (null? L)
(reverse r)
(loop (+ i 1)
(if (eq? (car L) A)
(cons i r)
r)
(cdr L))))))
顺便说一句:Scheme不是静态类型为C或Java。这意味着您不需要在保留变量值中编码错误,因为它在C中用-1完成。在计划中,您返回假#f
或空列表'()
或者您输入(error "Sorry")
错误。
提示:尝试使用正确对齐表达式的编辑器。这简化了Scheme的生活。例如,试试[Emacs](http://emacs.stackexchange.com/)。 – ceving
尤其是'emacs'和'paredit'。 –