我正在阅读一篇关于依赖类型编程的论文,并遇到了以下引用:
“[...] 与 Haskell 的类型类相比,数据类型 [...] 是封闭的”,从某种意义上说,如果不扩展数据类型,就无法向 Universe 添加新类型。
我的新手问题是:Haskell 类型的课程在什么意义上是开放的?它们如何扩展?此外,拥有此属性(开放与封闭)的类型理论后果是什么?
谢谢!
我正在阅读一篇关于依赖类型编程的论文,并遇到了以下引用:
“[...] 与 Haskell 的类型类相比,数据类型 [...] 是封闭的”,从某种意义上说,如果不扩展数据类型,就无法向 Universe 添加新类型。
我的新手问题是:Haskell 类型的课程在什么意义上是开放的?它们如何扩展?此外,拥有此属性(开放与封闭)的类型理论后果是什么?
谢谢!
类型类是开放的,因为您可以将任意类型作为它的实例。创建类型类时,您指定接口,但不指定属于它的类型。instance TypeClass type of
然后在任何包含 typeclass 定义的代码中,您可以使用语法使其类型实例从接口提供必要的功能。
给定一个类型类,如:
class Monoid m where
mempty :: m
mappend :: m -> m -> m
...它(基本上)在底层实现为字典类型:
data Monoid m = Monoid
{ mempty :: m
, mappend :: m -> m -> m
}
实例如:
instance Monoid [a] where
mempty = []
mappend = (++)
...被翻译成字典:
listIsAMonoid :: Monoid [a]
listIsAMonoid = Monoid
{ mempty = []
, mappend = (++)
}
...并且当您使用列表作为Monoid
s 时,编译器会参考上述字典。
这给我们带来了您的问题:
Haskell 类型的类在什么意义上是开放的?它们如何扩展?
它们是开放的,就像多态值是开放的一样。我们有一些多态数据类型:
data Monoid m = ...
...并且我们可以将多态类型变量实例化为可以为and字段m
提供合适值的任何类型。mempty
mappend
类型类是“开放的”,因为它们总是可以通过添加更多实例声明来“事后”添加更多类型。这甚至可以在仅使用包含类型类的模块的“客户端”代码中完成。
关键是我可以编写对具有某种类型类约束的值进行操作的代码,并且无需修改的相同代码可以用于在我编写类型类时不存在的类型。
Haskell 中的具体数据类型是“封闭的”,因为这不可能发生。如果我编写对特定数据类型的成员进行操作的代码(即使它是多态的),那么除非您能够修改类型,否则您将无法使用该代码来操作我没有想到的新事物(这可能需要修改所有使用它的地方)。
Ralf Laemmel在 Channel9 上有一些非常好的视频讲座- 强烈推荐。