gpt4 book ai didi

types - 任意类型说明符上的 Defmethod?

转载 作者:太空宇宙 更新时间:2023-11-03 18:37:25 25 4
gpt4 key购买 nike

我想做的是:

(defgeneric fn (x))

(defmethod fn ((x (integer 1 *)))
"Positive integer")

(defmethod fn ((x (integer * -1)))
"Negative integer")

我想要一个适用于任意类型说明符的通用函数,包括基于列表的说明符,例如 (and x y)(or x y) (满足 p) 等。现在,当我尝试运行上面的代码时,出现“无效的特化程序”错误。一些研究表明,defgeneric 旨在与 CLOS 一起使用,而不是与任意类型说明符一起使用。 Common Lisp 中是否有一个类似 defgeneric 的系统可以让我获得我想要的任意类型说明符的行为,而不仅仅是类?

最佳答案

Common Lisp 定义了两个相关但不相同的层次结构:类型层次结构和类层次结构。每个类都是一种类型,但反之则不然——有些类型不是类。例如,integerstring 是类,因此也是类型。另一方面,(integer 1 *)(satisfies evenp) 是类型,而不是类。

> (type-of "toto")
(SIMPLE-BASE-STRING 4)
> (class-of "toto")
#<BUILT-IN-CLASS STRING>

Parameter specialisers——你在 defmethod 中放在参数后面的东西——只能是类名(或 (eql value) 形式)。由于 (integer 1 *) 不是类名,Common Lisp 不允许使用您的代码。有一个很好的理由:编译器总是能够确定类层次结构,而类型语言对于它来说太强大了:

(defun satisfies-the-collatz-conjecture (n)
(cond
((<= n 1) t)
((evenp n) (satisfies-the-collatz-conjecture (/ n 2)))
(t (satisfies-the-collatz-conjecture (+ 1 (* n 3))))))

(subtypep 'integer '(satisfies satisfies-the-collatz-conjecture))
NIL ;
NIL

如果你真的需要你的代码是模块化的,你需要首先将你的值分类为可以制作成特化的东西,然后在上面调度:

(defmethod fn-generic (x (sign (eql 'positive)))
"Positive integer")

(defmethod fn-generic (x (sign (eql 'negative)))
"Negative integer")

(defun classify (x)
(cond
((< x 0) 'negative)
((= x 0) 'null)
((> x 0) 'positive)))

(defun fn (x)
(fn-generic x (classify x)))

关于types - 任意类型说明符上的 Defmethod?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27085443/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com