我正在阅读一篇关于依赖类型编程的论文,并且发现了以下引用:
“[...]与Haskell的类型类相反,数据类型[...]是关闭”,在某种意义上说,如果不扩展数据类型。
我的新手问题是:在什么意义上Haskell类型类打开?它们如何可扩展?此外,拥有此属性(开放式与封闭式)的类型理论后果是什么?
谢谢!
答案 0 :(得分:12)
类型类是打开的,因为您可以将任意类型作为它的实例。创建类型类时,指定接口,但不指定属于它的类型。然后在任何包含类型类定义的代码中,您可以使用instance TypeClass type of
语法从接口提供必要的函数。
答案 1 :(得分:9)
给定类型类:
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 = ...
...我们可以将多态m
类型变量实例化为任何类型,我们可以为mempty
和mappend
字段提供合适的值。
答案 2 :(得分:3)
类型类是“开放的”,因为它们总是可以通过添加更多实例声明来“在事后”添加更多类型。这甚至可以在仅仅使用包含类型类的模块的“客户端”代码中完成。
关键是我可以编写对具有某种类型类约束的值进行操作的代码,并且在编写类型类时,可以对不存在的类型使用相同的代码而不进行修改。
Haskell中的具体数据类型是“封闭的”,因为这不可能发生。如果我编写对成员运行特定数据类型的代码(即使它是多态的),那么除非你能够修改类型,否则你无法使用该代码来操作我没想过的新类型的东西。 (然后可能需要修改使用它的所有地方)。
答案 3 :(得分:2)
Ralf Laemmel对此有一些非常好的video lectures on Channel9 - 强烈推荐。