通用Lisp中的类型类

8
我想知道是否有一种方法可以在Common Lisp中模拟Haskell的typeclasses。
泛型函数允许重载,并且可以使用deftype定义类型(例如,可以通过成员身份来定义某些实例的列表)。
但是我无法根据类型进行分派。是否有一种方法在定义后使类成为另一个类的子类(和子类型)(例如,使cons类成为sequence类的子类,而不重新定义cons)?
谢谢。

2
Stackoverflow是最好的解决实际编程问题的平台,但对于猜测编程语言A是否支持编程语言B的功能不是很适用。 - Rainer Joswig
我有些犹豫是否要在这里发布,因为这似乎不仅涉及到是否,还涉及到如何实现这样一个功能(这是一个编程问题,对吧?)。无论如何,我会记住这点的。 - Charles Langlois
3
我想知道Lisp是否能够实现它。即使像Haskell一样的实现方式不相关,关于Lisp能否实现类型类是一个合理的问题。 - Jeffrey Benjamin Brown
2个回答

2
在Haskell中,类型类是一种在字典形式下静态查找“接口”实现的方式(类似于C++中虚函数表的使用但几乎完全静态,与C++在运行时进行动态分派不同)。然而,Common Lisp是一种动态类型语言,因此这样的查找毫无意义。但是,在像Common Lisp这样表达力强的语言中实现自己的“类型类”实现(实例)的查找并不太难想象。
附注:Python的Zope有一个非常相似的适应机制,如果您想引用动态环境中的现有解决方案,请参考它。

Haskell的实例字典并不比C++的虚函数表更加静态。它们在可能的情况下会在编译时进行特化,但否则它们确实是在运行时传递的。 - dfeuer
3
运行时已经通过,但没有动态查找,因为没有动态分派,也就是没有子类型多态性,又称(类型)继承 - 我错过了什么吗? - Erik Kaplun
1
我不确定。术语似乎有点模糊。在存在多态递归(即使在Haskell 98中)或GADTs(在真正的Haskell中),特定类型可能无法知道,特定实例可能直到运行时才存在。这不就是动态分派的本质吗? - dfeuer
我可能经验不足:你能提供一个例子吗?我想学习。另外,如果你所说的是真的,那么这是否意味着Haskell具有RTTI而不是完全的运行时类型抹消? - Erik Kaplun

-1
您无法按照您所设想的方式修改类继承结构,但您可以实现几乎相同的效果。
假设您对“序列”的定义是它具有函数“sequence-length”的方法。
(defclass sequence ...)
(defmethod sequence-length ((s sequence)) ...)

然后,您可以轻松地将sequence-length方法扩展为conses:

(defmethod sequence-length ((s cons))
    (length s))

这是否创建了一个包含cons的新类?实际上并没有。你可以通过说(or sequence cons)来表示具有sequence-length方法的事物的类型,但这并不是真正有用的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接