Scheme 方案(相当大)定义了一个;级别“;功能子
我试图在Scheme中定义一个函数,使用相当大的语言(在Dr.Racket中),它将获取一个列表,并将所有“原子”转换为顶级元素。例如,如果给出:Scheme 方案(相当大)定义了一个;级别“;功能子,scheme,lambda,Scheme,Lambda,我试图在Scheme中定义一个函数,使用相当大的语言(在Dr.Racket中),它将获取一个列表,并将所有“原子”转换为顶级元素。例如,如果给出: (level '(a b (c d) (e f (g 4 h)))) ;=> (a b c d e f g 4 h) 以下是我目前掌握的代码: ;;level -takes list and returns list w/all elements as top-level (define level (lambda (L) (co
(level '(a b (c d) (e f (g 4 h))))
;=> (a b c d e f g 4 h)
以下是我目前掌握的代码:
;;level -takes list and returns list w/all elements as top-level
(define level
(lambda (L)
(cond ((null? L) L)
((not( pair? L)) L)
(else (append (level(car L)) (level(cdr L)))))))
我的错误如下:
append: contract violation
expected: list?
given: d
有人能帮我解决这个错误吗?在列表上追加工作。如果您使用列表调用
level
(1 2 3)第一次迭代它将执行(append(level'1)(level(cdr'(2 3)))
。现在“1”不是一对,因此将计算为1,这是而不是列表。这将类似于调用(append'1…
,这是违反合同的
编辑
这是一个相当大的flatte
实现。它基于Chris Jester Young的。它比append
版本更有效
(define (flatten lst)
;; helper function that accumulates
(define (reverse-flatten-into x lst)
(if (pair? x)
(foldl reverse-flatten-into lst x)
(cons x lst)))
(reverse (reverse-flatten-into lst '())))
Append对列表有效。如果您使用列表调用
level
(1 2 3)第一次迭代它将执行(Append(level“1”)(level(cdr)(2 3))
。现在“1”不是一对,因此将计算为1,这是而不是列表。这就像调用(APPEPEND“1…”
,这是违反合同的行为
编辑
这是一个相当大的flatte
实现。它基于Chris Jester Young的。它比append
版本更有效
(define (flatten lst)
;; helper function that accumulates
(define (reverse-flatten-into x lst)
(if (pair? x)
(foldl reverse-flatten-into lst x)
(cons x lst)))
(reverse (reverse-flatten-into lst '())))
Append对列表有效。如果您使用列表调用
level
(1 2 3)第一次迭代它将执行(Append(level“1”)(level(cdr)(2 3))
。现在“1”不是一对,因此将计算为1,这是而不是列表。这就像调用(APPEPEND“1…”
,这是违反合同的行为
编辑
这是一个相当大的flatte
实现。它基于Chris Jester Young的。它比append
版本更有效
(define (flatten lst)
;; helper function that accumulates
(define (reverse-flatten-into x lst)
(if (pair? x)
(foldl reverse-flatten-into lst x)
(cons x lst)))
(reverse (reverse-flatten-into lst '())))
Append对列表有效。如果您使用列表调用
level
(1 2 3)第一次迭代它将执行(Append(level“1”)(level(cdr)(2 3))
。现在“1”不是一对,因此将计算为1,这是而不是列表。这就像调用(APPEPEND“1…”
,这是违反合同的行为
编辑
这是一个相当大的flatte
实现。它基于Chris Jester Young的。它比append
版本更有效
(define (flatten lst)
;; helper function that accumulates
(define (reverse-flatten-into x lst)
(if (pair? x)
(foldl reverse-flatten-into lst x)
(cons x lst)))
(reverse (reverse-flatten-into lst '())))
有关如何实现展平的更多信息,请参阅
append
要求其所有参数(通常需要两个以上)都是列表。例如
> (append '(1 2 3) '(4 5 6))
;=> (1 2 3 4 5 6)
> (append '(1 2 3) '(4 5 6) '(7 8 9))
;=> (1 2 3 4 5 6 7 8 9)
现在,您正在编写函数,您说过level
应该返回一个列表。这意味着如果level
有几个不同的执行路径,每个路径都需要生成一个列表。那么,让我们看看您的实现
(define level
(lambda (L)
(cond ((null? L) L)
((not( pair? L)) L)
(else (append (level(car L)) (level(cdr L)))))))
在问题中,您说您正在编写一个函数,它应该包含一个列表,因此L
可以是两种情况之一;它可以是空列表,也可以是一对。不过,目前您的cond
有三种情况
(cond ((null? L) L) ; handle an empty list
((not( pair? L)) L)
(else (append (level(car L)) (level(cdr L))))) ; handle a pair
如果您总是使用列表调用level
,则不需要第二种情况。但是,因为在第三种情况下,您确实调用(level(car L))
,并且您不知道是否(car L)
将是一个列表,似乎您最终会使用非列表调用级别
。您需要决定,例如,(级别“a”)
是否应该合法,如果应该,应该是什么。目前,似乎您正试图使(级别“a”)合法并返回(a)
。这很好,但是你应该指定合同。如果这是你想要做的,那么你确实需要在你的条件中使用第二个案例,但是由于(a级)
应该返回(a)
,你实际上需要该案例返回(列表L)
,而不是L
这里的另一个选项是,如果您确实希望level
严格,并且总是需要一个列表作为参数,那么您需要添加更多的逻辑来确定(car L)
是一个列表,如果是,则递归调用其上的level
,然后调用append
,并生成结果。一种方法如下:
(define (level L)
(cond
((null? L) L)
((pair? L) (append (if (list? (car L))
(level (car L))
(list L))
(level (cdr L))))))
有关如何实现展平的更多信息,请参阅
至于您的特定错误,append
要求其所有参数(通常需要两个以上)都是列表。例如
> (append '(1 2 3) '(4 5 6))
;=> (1 2 3 4 5 6)
> (append '(1 2 3) '(4 5 6) '(7 8 9))
;=> (1 2 3 4 5 6 7 8 9)
现在,您正在编写函数,您说过level
应该返回一个列表。这意味着如果level
有几个不同的执行路径,每个路径都需要生成一个列表。那么,让我们看看您的实现
(define level
(lambda (L)
(cond ((null? L) L)
((not( pair? L)) L)
(else (append (level(car L)) (level(cdr L)))))))
在问题中,您说您正在编写一个函数,它应该包含一个列表,因此L
可以是两种情况之一;它可以是空列表,也可以是一对。不过,目前您的cond
有三种情况
(cond ((null? L) L) ; handle an empty list
((not( pair? L)) L)
(else (append (level(car L)) (level(cdr L))))) ; handle a pair
如果您总是使用列表调用level
,则不需要第二种情况。但是,因为在第三种情况下,您确实调用(level(car L))
,并且您不知道是否(car L)
将是一个列表,似乎您最终会使用非列表调用级别
。您需要决定,例如,(级别“a”)
是否应该合法,如果应该,应该是什么。目前,似乎您正试图使(级别“a”)合法并返回(a)
。这很好,但您应该指定t