【问题标题】:Why does List function call return runtime error in Scheme?为什么 List 函数调用在 Scheme 中会返回运行时错误?
【发布时间】:2021-02-23 00:54:54
【问题描述】:

我在方案中创建的二叉搜索树出现错误。

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

这是我的代码。我认为错误与我调用函数的方式有关,但我不确定到底是什么问题。我使用两个必需参数调用插入函数:树和值 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

【问题讨论】:

  • 无法在更成熟的实现中重现 您的解释器可能会在结尾处因语法错误而窒息。 (Gauche 甚至还不是 1.0 版,所以 bug 不足为奇。)

标签: functional-programming scheme


【解决方案1】:

您关心呼叫(member t 5),这与(member '(10 '() '()) 5) 相同。现在member 与您定义的member? 不同,因为它具有不同的名称。 member 是核心库,看起来像这样:

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

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

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

括号的缩进和放置不是goo lisp风格。你的代码应该这样写:

;; 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 2014-12-16
    • 2022-10-04
    • 1970-01-01
    相关资源
    最近更新 更多