检查参数是否为点对而不是列表

时间:2018-10-29 06:49:52

标签: scheme racket

我刚刚开始学习球拍,我必须检查一个参数是否为点对。

我已经尝试过了:

(pair? '(a . 1))

并返回#t

(pair? '('(a b c) . 1))

并返回#t

(pair? '(a b c))

并返回#t。但是我想在这种情况下得到#f。

是否只有当我将虚线对作为参数传递给它时,pair?这样的另一个程序才能实现?

也许我将必须执行一个程序来检查它是否不是列表,然后再检查它是否是一对。

更新
我只需要检查'(a . 1)是一个点对,并且任何列表都不是点对。

2 个答案:

答案 0 :(得分:4)

如果我们是个学究的人,虚线对只不过是一种记号,一种写成对的方式。表达式’(a . d)的计算结果为cons单元格。

将函数应用于某些参数时,参数为值。这意味着一个函数不能接收点对-它可以接收一个cons单元。

好的-但是函数可以知道一个值是con单元格还是列表?取决于你的意思。列表表示为null(空列表)或cons单元格,其第二个元素为列表。

因此,谓词pair?对于所有列表(空列表除外)将返回true。 现在,我们可以通过写入(and (pair? x) (not (list? x)))来检查cons单元格是否不是列表的第一个cons单元格。

答案 1 :(得分:3)

我不知道用于过滤点对的内置函数。但是实现一个应该很简单。只需检查参数是否是一个包含多个元素的列表,并且列表中的cdr本身就不是一对。

这是一个示例实现。

(define (not-list-dotted-pair? x)
  (and
    (pair? x)
    (not (null? (cdr x)))
    (not (pair? (cdr x)))))