我是Scheme的新手,当我尝试使用此功能时,我遇到了“格式错误的特殊形式”错误。如果原始的长度为0,我希望函数返回 left 。否则我希望它执行追加调用和递归调用。我想我可能做了一些非常愚蠢的事情。有帮助吗?
(define (partition left right original)
(if (= (length original) 0) left
(append left (car original))
(append right (car (reverse original)))
(partition left right (reverse original))))
答案 0 :(得分:2)
if
表单由4部分组成:
if
。您的if
- 表单由6部分组成。 (= (length original) 0)
是条件。 left
是then-branch,(append left (car original))
是else-branch。但其他两个应该是什么?对于读者来说显而易见的是,他们仍然应该成为else分支的一部分,但编译器无法知道。就编译器而言,您可能也希望left
和(append left ...)
进入then-branch,而其他两个进入else
分支。
如果要在if
内执行多个表达式,则需要某种方法将属于同一分支的表达式组合在一起。你可以使用begin
这样做:
(if condition
(begin
(do-something-in-the-then-branch)
(do-something-else-in-the-then-branch))
(begin
(do-something-in-the-else-branch)
(do-something-else-in-the-else-branch)))
然而,在您的情况下,这实际上并没有帮助,因为append
无法就地工作。即如果您执行(append left (car original))
,则left
的值实际上无法更改。相反,append
将返回包含left
和(car original)
内容的新列表,而不会实际更改任何列表。因此,要使用append
的结果,您需要使用其返回值。
因此,为了使您的函数正常工作,您应该将调用直接作为参数传递给partition
或使用let
将结果分配给变量并将变量传递给partition
答案 1 :(得分:2)
在开始之前,请尝试indent your programs properly。在这种情况下,它会使错误更加明显。
你正在遇到许多计划新手来自其他语言的速度爆炸:
Lisp中的 if
(包括scheme)实际上是三元运算符,而不是来自C类世界的if
块。
您的代码尝试以超过三种形式呈现if
,因此失败。天真地,你可以做的是使用块构造begin
(Common Lisp中的progn
)来确保条件的单个分支只包含一个表单。
(define (partition left right original)
(if (= (length original) 0)
left
(begin
(append left (car original))
(append right (car (reverse original)))
(partition left right (reverse original)))))
现在,我感觉这不会做你想要的,因为append
是有效的(也就是说,它返回一个结果而不修改它的参数)。换句话说,您对append
的任何呼叫都不会执行任何操作,original
永远不会缩短。你实际上似乎想要的是
(define (partition left right original)
(if (= (length original) 0)
left
(partition (cons (car original) left)
(cons (last original) right)
(cdr (take original (- (length original) 1))))))