为什么List函数调用Scheme时返回运行时错误



我在scheme中创建的二进制搜索树出现错误。

$gosh main.sc
*** ERROR: list required, but got 5
Stack Trace:
_______________________________________

这是我的密码。我认为这个错误与我如何调用函数有关,但我不确定到底出了什么问题。我使用两个必需的参数调用insert函数:树和值5。

(define (member? t v)
(cond 
((null? t)
#f
)
((< node (car t))
(member? (cadr t) v))
((> node (car t))
(member? (caddr t) v))
(else
#t
)
)
)
(define (insert t v)
(cond
((null? t)
(list v '() '())
)
((< v (car t))
(list (car t) (insert (cadr t) v) (caddr t))
)
((>= v (car t)) 
(list (car t) (cadr t) (insert (caddr t) v))
)
(else
t
)
)
)

(define (fold func val lst)
(if (null? lst) val (fold func (func val (car lst)) (cdr lst))))
(define (build lst)
(fold (lambda (t v) (insert t v)) '() lst))
(define t (list 10 '() '()))
(insert t 5)
display  (member t 5)
display t

您需要调用与(member '(10 '() '()) 5)相同的(member t 5)。现在member与您定义的member?不同,因为它有不同的名称。member是如下所示的核心库:

(define (member obj lst)
(cond ((null? lst) #f)
((equal? obj (car lst)) lst)
(else (member obj (cdr lst)))))

您的member?交换了两个参数,因此当您写错名称并使用报告版本member时,5不为空,那么它将执行(car 5),这将非常失败。5不是所需类型list的错误消息相当不错。它可能会拼写出是member失败了。

另一件事。如果将对member的调用替换为对member?的调用,则会遇到更多问题。您使用的变量node没有在任何地方定义。

括号的缩进和放置不是古里索普风格的。你的代码应该这样写:

;; node doesn't exist in OPs code, but my implementation doesn't like member? without it
(define node 5)
;; possible typo by using the variable node ?
(define (member? t v)
(cond
((null? t)
#f)
((< node (car t))
(member? (cadr t) v))
((> node (car t))
(member? (caddr t) v))
(else
#t)))
(define (insert t v)
(cond
((null? t)
(list v '() '()))
((< v (car t))
(list (car t) (insert (cadr t) v) (caddr t)))
((>= v (car t))
(list (car t) (cadr t) (insert (caddr t) v)))
(else 
t)))

(define (fold func val lst)
(if (null? lst) val (fold func (func val (car lst)) (cdr lst))))
(define (build lst)
(fold (lambda (t v) (insert t v)) '() lst))
(define t (list 10 '() '()))
(insert t 5)
;; NB doesn't call a procedure, just evaluates it. 
display
;; Here the arguments are the wrong order and you don't use memeber?
(member t 5)
;; NB doesn't call a procedure, just evaluates it. 
display
t

最新更新