【发布时间】:2025-12-18 16:00:02
【问题描述】:
“普通”函数通常只定义在给定类型的对象域上,但某些函数,例如 Scheme 类型谓词 list? 或 procedure?,是为任何类型的参数定义的,甚至可以是适用于自己。所以例如(list? procedure?) 的计算结果为 #f,(procedure? procedure?) 的计算结果为 #t。我试图弄清楚如何编写这种完全定义的函数,但一直无法找到讨论这个问题的来源。
例如,假设我们使用以下构造函数和选择器实现Structure and Interpretation of Computer Programs 的练习 2.4 中描述的对数据类型:
(define (cons x y)
(lambda (m) (m x y)))
(define (car z)
(z (lambda (p q) p)))
(define (cdr z)
(z (lambda (p q) q)))
然后我将如何定义一个谓词pair?,它为使用cons 构造的任何东西返回#t,而对于不是使用#f 构造的任何东西都返回#f?更一般地说,list? 和 procedure? 这样的类型谓词是如何实现的?
【问题讨论】:
-
你为什么要关心这对是如何构建的?如果是一对,那么无论如何都是一对。您可以将
pair?定义为一个不为空的列表,并且其cdr 不为空,但cdr 上的递归为#f。我很确定list?谓词需要是一个内置函数,因为它太基础了。 -
@d11wtq
(define (list? x) (and (pair? x) (or (null? (cdr x)) (list? (cdr x)))))检查参数对象是否是一个有限的正确列表。pair?只检查它是否是一个 cons 单元数据对象。(let ((a (list 1))) (set-cdr! a a) (pair? (cdr a)))必须能够返回#t。
标签: types scheme racket predicate