car/cdr 参数是列表...对吗?

car/cdr arguments are lists... right?

我在Scheme中做了一个名为chatbot的字符串列表

聊天机器人中的每个列表元素都有字符串。我正在尝试使用不同的列表对这些字符串进行分类,这些列表都存储在一个名为 chatbot 的大列表中。 (抱歉冗余)

为了清楚起见,这里是执行此操作的代码:

(define greetings '("string 1"
                    "string 2"
                    "string 3"
                    "string 4"))

(define cheerUpPhrases '("string 5"
                         "string 6"))

(define congratsPhrases '("string 7"
                          "string 8))

(define didNotUnderstand '("string 8"
                           "string 9"
                           "string 10"))

(define chatbot '(greetings cheerUpPhrases congratsPhrases didNotUnderstand))

我真的觉得这样还可以。但是后来,在一个函数中,我想得到 "string 3" 所以我尝试这样做:

(caddar chatbot)

然后得到这个错误:

caddar: contract violation
expected: (cons/c (cons/c any/c (cons/c any/c pair?)) any/c)
given: '(greetings cheerUpPhrases congratsPhrases didNotUnderstand)

不太清楚那是什么意思,我把(caddar chatbot)改成了:

(third (car chatbot))

最后,我得到了这个错误:

third: contract violation
expected: list?
given: 'greetings

现在,我明白(第三个)需要一个列表(实际上是一对)才能工作; car/cdr 和类似的功能也是如此。毕竟我不给它一个清单吗?我现在真的很迷茫。

我刚刚开始学习 Scheme 和函数范式,所以我可能遗漏了一个基本的东西。如果你能向我解释发生了什么,那将真的对我有帮助。

提前致谢。

关闭。问题是你误用了 '.

你看,'(a b c) 不会扩展为 (list a b c),而是扩展为 (list 'a 'b 'c)

因此,您没有插入列表 greetingscheerUpPhrasescongratsPhrasesdidNotUnderstand,而是按字面意思将它们作为符号插入。

有两种简单的方法可以解决这个问题。您可以使用准引用 ` 和取消引用 ,,或者您可以直接使用 list。使用 list 重写您的代码(并修复损坏的 "string 8" 给出:

(define greetings '("string 1"
                    "string 2"
                    "string 3"
                    "string 4"))

(define cheerUpPhrases '("string 5"
                         "string 6"))

(define congratsPhrases '("string 7"
                          "string 8"))

(define didNotUnderstand '("string 8"
                           "string 9"
                           "string 10"))

(define chatbot (list greetings cheerUpPhrases congratsPhrases didNotUnderstand))

您现在可以看到 chatbot 变量包含您期望的实际列表:

> chatbot
'(("string 1" "string 2" "string 3" "string 4") ("string 5" "string 6") ("string 7" "string 8") ("string 8" "string 9" "string 10"))