了解Hindley的多型体

我正在阅读关于Hindley-Milner Type推理的维基百科文章,试图从中得出一些意见。 到目前为止,这是我所理解的:

  • 类型被分类为单形或多形。
  • Monotypes进一步分为类型常量(如intstring )或类型变量(如αβ )。
  • 类型常量可以是具体类型(如intstring )或类型构造函数(如MapSet )。
  • 类型变量(如αβ )表现为具体类型的占位符(如intstring )。
  • 现在我在理解多类型时遇到了一些困难,但是在了解一下Haskell之后,我就这样做了:

  • 类型本身有类型。 正式的类型被称为种类(即有不同种类的类型)。
  • 具体类型(如intstring )和类型变量(如αβ )是*类型的。
  • 类型构造函数(如MapSet )是类型的lambda抽象类型(例如Set是kind * -> *Map是kind * -> * -> * )。
  • 我不明白的是限定词是什么意思。 例如, ∀α.σ代表什么? 我似乎无法做出正面或反面的结论,而我越读越接下去的段落就越感到困惑:

    相反, polytype∀α.α - >α的函数可以将任何相同类型的值映射到自身,并且标识函数是此类型的值。 作为另一个例子∀α。(Setα) - > int是将所有有限集合映射到整数的函数的类型。 成员的数量是这种类型的值。 请注意,限定符只能出现在顶层,即例如类型∀α.α->∀α.α被类型语法排除,并且单型包含在多类型中,因此类型的一般形式为∀α1。 ∀αₙ.τ


    首先,种类和多态类型是不同的东西。 你可以有一个HM类型的系统,其中所有类型都是相同类型的(*),你也可以有一个没有多态性但复杂类型的系统。

    如果一个术语M的类型是∀at ,就意味着对于任何类型s我们可以替代sat (通常写为t[a:=s]我们将具有M的类型为t[a:=s] 。这有点类似于逻辑,我们可以用任何一个术语代替普遍量化的变量,但在这里我们正在处理类型。

    这正是Haskell发生的情况,就是在Haskell中你看不到量词。 出现在一个类型签名的所有类型的变量都隐含量化,就像如果你有forall在类型的前面。 例如, map会有类型

    map :: forall a . forall b . (a -> b) -> [a] -> [b]
    

    如果没有这种隐式通用量化,类型变量ab必须有一些固定的含义,并且map不会是多态的。

    HM算法区分类型(不含量词,单式)和类型模式(通用量化类型,多型)。 在某些地方使用类型模式(如let )很重要,但在其他地方只允许使用类型。 这使得整个事情可以决定。

    我也建议你阅读有关系统F.文章这是一个比较复杂的系统,它允许forall的类型(因此那里的一切就被称为类型)的任何地方,但类型推断/检查是不可判定的。 它可以帮助您了解forall的作品。 F系统在Girard,Lafont和Taylor的Proofs和Types中有深入的描述。


    考虑Haskell中的l = x -> t 。 它是λ,它表示一个术语t FITH变量x ,这将在后面被取代的(例如l 1 ,不管它意味着)。 类似地, ∀α.σ表示具有类型变量类型α ,即, f : ∀α.σ如果一个函数由类型参数α 。 在某种意义上, σ取决于α ,因此f返回类型σ(α)的值,其中α将在后面的σ(α)被替换,我们将得到一些具体类型。

    在Haskell中,您可以省略并像id : a -> a一样定义函数。 允许省略量词的原因基本上是因为它们只允许顶级(没有RankNTypes扩展名)。 你可以试试这段代码:

    id2 : a -> a -- I named it id2 since id is already defined in Prelude
    id2 x = x
    

    如果你问ghci的id:t id )的类型,它会返回a -> a 。 为了更精确(更多类型理论), id的类型为∀a. a -> a ∀a. a -> a 。 现在,如果你添加到你的代码:

    val = id2 3
    

    ,3具有的类型Int ,如此的类型Int将被代入σ ,我们会得到一个具体类型Int -> Int

    链接地址: http://www.djcxy.com/p/14199.html

    上一篇: Understanding Polytypes in Hindley

    下一篇: What is Hindley