类型类的数学(分类)描述


14

可以将功能语言视为一种类别,其中它的对象是类型,而词素之间是功能。

类型类如何适合此模型?

我假设我们应该只考虑那些满足大多数类型类所具有的约束但在Haskell中未表达的约束的实现。例如,我们应该只考虑Functor针对fmap id ≡ id和的那些实现fmap f . fmap g ≡ fmap (f . g)

还是类型类型有其他理论基础(例如基于类型化的lambda计算)?


1
您可能想更明确地了解模型的确切用途。如果您想要一些可以严格描述开放世界假设的东西,实例解析的行为,各种GHC扩展的相互作用等等,则比理想化版本要复杂得多。同样,请注意,讨论Hask时经常忽略底部。
CA McCann

4
类型类可以视为签名(在通用代数意义上)。共享相同签名(相同类型类的元素)的所有实体的集合是多种多样的
戴夫·克拉克2012年

1
@DaveClarke:对我而言,如何用这种方式描述高等类型的类型类并不是立即显而易见的,但是我对通用代数并不十分熟悉,并且可能会误解您所想的对应关系……
CA McCann 2012年

1
@camccann:我不确定通信往多远。当然,这似乎是一个很好的起点。
戴夫·克拉克2012年

2
@camccann:只需更改定义代数的基本类别即可:num等基本类型类是haskell类型(或Hsk类别的对象)类别上的签名,类型构造函数上的类型类别是函子类别上的代数从Hask到Hask。注意,通用代数完全被范畴理论中的代数概念所包含。另外:戴夫:您应该将您的评论变成答案。
科迪2012年

Answers:


18

类型类如何适合此模型?

简短的答案是:他们没有。

每当您在语言中引入强制性,类型类或其他用于特殊多态性的机制时,面临的主要设计问题就是一致性

基本上,您需要确保类型类解析是确定性的,以便类型正确的程序具有单一解释。例如,如果您可以在同一范围内为同一类型提供多个实例,则可能会编写如下这样的模棱两可的程序:

class Blah a where
   blah : a -> String 

instance Blah T where
   blah _ = "Hello"

instance Blah T where
   blah _ = "Goodbye"

v :: T = ...

main :: IO ()
main = print (blah v)  -- does this print "Hello" or "Goodbye"?

根据编译器选择的实例,blah v可以等于"Hello""Goodbye"。因此,程序的含义将不会完全由程序的语法确定,而是会受到编译器做出的任意选择的影响。

Haskell解决此问题的方法是要求每种类型每个类型类最多具有一个实例。为确保这一点,它仅允许在顶级执行实例声明,并且还使所有声明在全局范围内可见。这样,如果进行了模棱两可的实例声明,则编译器始终可以发出错误信号。

但是,使声明在全局范围内可见会破坏语义的组合性。要恢复,您需要做的是为编程语言提供详尽的语义 -即,您可以展示如何将Haskell程序转换为行为更佳,组成更多的语言。

实际上,这实际上也为您提供了一种编译类型类的方法-在Haskell圈子中通常称为“证据翻译”或“字典传递转换”,并且是大多数Haskell编译器的早期阶段之一。

类型类也是编程语言设计与纯类型理论不同的一个很好的例子。类型类是一个非常了不起的语言功能,但是从证明理论的角度来看,它们的行为很不正确。(这就是为什么Agda根本没有类型类的原因,也是为什么Coq使其成为启发式推理基础结构的一部分。)


什么是亚军候选人是具有指称语义iyswim?
Ohad Kammar 2012年

1
我不知道,a。
Neel Krishnaswami 2012年

这是否值得提出其他问题?
Ohad Kammar

@NeelKrishnaswami:您是否知道ML模块如何适用于此?那Agda模块呢(有人对我说的是“一流”)?
2013年

1
@Lii:ML模块和Agda记录是 的表现好得多,但是它太复杂了,无法在注释中进行解释-提出有关它们的问题,我(或其他人)将进行解释。
Neel Krishnaswami
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.