可扩展的Haskell类型类

时间:2013-04-12 09:02:54

标签: haskell typeclass extensible

我正在阅读一篇关于依赖类型编程的论文,并且发现了以下引用:

“[...]与Haskell的类型类相反,数据类型[...]是关闭”,在某种意义上说,如果不扩展数据类型。

我的新手问题是:在什么意义上Haskell类型类打开?它们如何可扩展?此外,拥有此属性(开放式与封闭式)的类型理论后果是什么?

谢谢!

4 个答案:

答案 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类型变量实例化为任何类型,我们可以为memptymappend字段提供合适的值。

答案 2 :(得分:3)

类型类是“开放的”,因为它们总是可以通过添加更多实例声明来“在事后”添加更多类型。这甚至可以在仅仅使用包含类型类的模块的“客户端”代码中完成。

关键是我可以编写对具有某种类型类约束的值进行操作的代码,并且在编写类型类时,可以对不存在的类型使用相同的代码而不进行修改。

Haskell中的具体数据类型是“封闭的”,因为这不可能发生。如果我编写对成员运行特定数据类型的代码(即使它是多态的),那么除非你能够修改类型,否则你无法使用该代码来操作我没想过的新类型的东西。 (然后可能需要修改使用它的所有地方)。

答案 3 :(得分:2)

Ralf Laemmel对此有一些非常好的video lectures on Channel9 - 强烈推荐。