Scheme对象不适用 - 有两种不同的方式

时间:2016-04-08 00:42:58

标签: scheme

我正在为计划中的名册管理程序编写一些代码,但在我尝试添加学生时会遇到问题。我使用的是名单参数,这是一个列表列表,每个子列表都是学生的记录。我添加的第一个学生没有问题,但是当我尝试添加第二个学生时,我会收到同样错误的两个实例中的一个。

如果我尝试输入应该添加的学生,我会收到错误:

The object ("21" "Anon Ymous" "89") is not applicable.

如果我添加的学生的信息与现有学生有冲突,我会收到错误:

The object (("23" "Anon Ymous" "11")) is not applicable.

本节的代码如下:

(define addifnotcontains
    (lambda (roster item)
        (cond ((null? roster) (list item))
            ((equal? (car (car roster)) (car item))
                (begin
                    (display "\tID Already Exists\n")
                    (roster)
                ))
            ((equal? (cadr (car roster)) (cadr item)) 
                (begin
                    (display "\tName Already Exists\n")
                    (roster)
                ))
            (else (cons ((car roster) addifnotcontains (cdr roster))))
        )
    )
)

并且对此函数的调用是(menu (addifnotcontains roster (buildobject 0 '()))),其中menu是lambda函数,只需要一个名单

我知道这个问题是由我之前的代码中的括号不匹配或错位引起的,但我不知道为什么这次会发生。我怀疑它与在开始块结束时调用(roster)有关,但据我所知,开始块返回块内调用的最后一个值。我做错了什么?

1 个答案:

答案 0 :(得分:1)

在第一种情况下,您尝试将(car roster)应用于addifnotcontains(cdr roster)

(cons ((car roster) addifnotcontains (cdr roster)))
      ^   <--    This is one expression   -->    ^ 

您也只是将一个参数传递给cons 并且忘记传递item

这应该是

(cons (car roster) (addifnotcontains (cdr roster) item))

在第二种情况下,您尝试将roster作为函数应用。

你是正确的,因为begin块的值是块中最后一个表达式的值,但在你的情况下,这个表达式应该是roster,而不是(roster)
(请记住,您无法在Scheme中添加括号,就像在其他语言中一样;括号总是重要。)