简体   繁体   English

可扩展的Haskell类型类

[英]Extensible Haskell Type Classes

I am reading a paper on dependently-typed programming and came across the following quote: 我正在阅读一篇关于依赖类型编程的论文,并且发现了以下引用:

"[...] in contrast to Haskell's type classes, the data type [...] is closed ", in the sense that one cannot add new types to the universe without extending the data type. “[...]与Haskell的类型类相比,数据类型[...]是封闭的 ”,在某种意义上说,如果不扩展数据类型,就无法向Universe添加新类型。

My newbie question is: in what sense are Haskell type classes open ? 我的新手问题是:Haskell类型类在什么意义上打开 How are they extensible? 它们如何可扩展? Also, what are the type-theoretical consequences of having this property (open vs closed)? 此外,拥有此属性(开放与已关闭)的类型理论后果是什么?

Thank you! 谢谢!

Type classes are open, because you can make arbitrary type an instance of it. 类型类是打开的,因为您可以使任意类型成为它的实例。 When you create type class you specify interface, but not the types which belong to it. 创建类型类时,指定接口,但不指定属于它的类型。 Then in any code which includes typeclass definition you can make your type instance of it providing necessary functions from interface using instance TypeClass type of syntax. 然后在包含类型类定义的任何代码中,您可以使用它的类型实例从接口使用instance TypeClass type of语法提供必要的函数。

Given a type class like: 给定类型类:

class Monoid m where
    mempty  :: m
    mappend :: m -> m -> m

... it is (basically) implemented under the hood as a dictionary type: ...它(基本上)作为字典类型在引擎盖下实现:

data Monoid m = Monoid
    { mempty  :: m
    , mappend :: m -> m -> m
    }

Instances like: 例如:

instance Monoid [a] where
    mempty  = []
    mappend = (++)

... get translated to dictionaries: ...被翻译成词典:

listIsAMonoid :: Monoid [a]
listIsAMonoid = Monoid
    { mempty  = []
    , mappend = (++)
    }

... and the compiler consults above dictionary whenever you use lists in their capacity as Monoid s. ...当编译器使用Monoid s作为列表时,编译器会查询上面的字典。

This brings us to your questions: 这带给我们你的问题:

in what sense are Haskell type classes open? 在什么意义上Haskell类型类打开? How are they extensible? 它们如何可扩展?

They are open in the same sense that polymorphic values are open. 它们是开放的,就像多态值是开放的一样。 We have some polymorphic data type: 我们有一些多态数据类型:

data Monoid m = ...

... and we can instantiate the polymorphic m type variable to any type where we can provide suitable values for the mempty and mappend fields. ...我们可以将多态m类型变量实例化为任何类型,我们可以为memptymappend字段提供合适的值。

Type classes are "open" because they can always have more types added to them "after the fact" by adding more instance declarations. 类型类是“开放的”,因为它们总是可以通过添加更多实例声明“事后”添加更多类型。 This can even be done in "client" code that merely uses the module containing the type class. 这甚至可以在仅使用包含类型类的模块的“客户端”代码中完成。

The key point is that I can write code that operates on values with some type-class constraint, and that same code with no modification can be used on types that weren't in existence when I wrote the type class. 关键点在于我可以编写对具有某种类型类约束的值进行操作的代码,并且在我编写类型类时,可以对不存在的类型使用相同的代码而不进行修改。

Concrete data types in Haskell are "closed" in that this cannot happen. Haskell中的具体数据类型是“封闭的”,因为这不可能发生。 If I write code that operates on members a specific data type (even if it's polymorphic), then there's no way you can use that code to operate on new kinds of thing I hadn't thought of unless you're able to modify the type (which then probably requires modifying all the places where it is used). 如果我编写对成员运行特定数据类型的代码(即使它是多态的),那么除非你能够修改类型,否则你无法使用该代码来操作我没想过的新类型的东西。 (然后可能需要修改使用它的所有地方)。

Ralf Laemmel 在Channel9上有一些关于此的非常好的视频讲座 - 强烈推荐。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM