Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 什么是类型量词?_Haskell_Types_Ocaml_Existential Type_Parametric Polymorphism - Fatal编程技术网

Haskell 什么是类型量词?

Haskell 什么是类型量词?,haskell,types,ocaml,existential-type,parametric-polymorphism,Haskell,Types,Ocaml,Existential Type,Parametric Polymorphism,许多静态类型语言具有参数多态性。例如,在C#中,可以定义: T Foo<T>(T x){ return x; } 我听人说过“forall就像类型级别的lambda抽象”。所以Foo是一个接受类型(例如int)并生成值(例如int->int类型的函数)的函数。许多语言推断类型参数,因此您可以编写Foo(3),而不是Foo(3) 假设我们有一个对象f,类型为forall T.T->T。我们可以对这个对象做的是首先通过写入f将类型Q传递给它。然后我们返回一个类型为Q->Q的值。但是,某

许多静态类型语言具有参数多态性。例如,在C#中,可以定义:

T Foo<T>(T x){ return x; }
我听人说过“forall就像类型级别的lambda抽象”。所以Foo是一个接受类型(例如int)并生成值(例如int->int类型的函数)的函数。许多语言推断类型参数,因此您可以编写
Foo(3)
,而不是
Foo(3)

假设我们有一个对象
f
,类型为
forall T.T->T
。我们可以对这个对象做的是首先通过写入
f
将类型
Q
传递给它。然后我们返回一个类型为
Q->Q
的值。但是,某些
f
无效。例如,此
f

f<int> = (x => x+1)
f<T> = (x => x)
所以有两个部分需要讨论:一个用于量化的集合(例如整数)和一个谓词(例如p)。Forall可被视为一个高阶函数:

forall n in Integers: P(n) == forall(Integers,P)
类型:

forall :: Set<T> -> (T -> bool) -> bool
存在就像一个无限的析取:

exists(S,P) = P(S[0]) ∨ P(S[1]) ∨ P(S[2]) ...
如果我们用类型做类比,我们可以说∧ 正在计算交叉点类型∩, 和类似物的类型∨ 计算并集类型∪. 然后,我们可以定义forall并在类型上存在,如下所示:

forall(S,P) = P(S[0]) ∩ P(S[1]) ∩ P(S[2]) ...
exists(S,P) = P(S[0]) ∪ P(S[1]) ∪ P(S[2]) ...
所以forall是一个无限交集,exists是一个无限并集。它们的类型将是:

forall, exists :: Set<T> -> (T -> Type) -> Type
现在,对于所有T:类型,类型为
。T->T
是一个值,而不是从类型到值的函数。它是一个值,其类型是所有类型T->T的交集,其中T范围覆盖所有类型。当我们使用这样的值时,我们不必将其应用于类型。相反,我们使用子类型判断:

id :: forall T:Type. T -> T
id = (x => x)

id2 = id :: int -> int
这将使
id
具有类型
int->int
。这是有效的,因为
int->int
也出现在无限交点中

我认为这很好,它清楚地解释了forall是什么以及它与lambda的区别,但是这个模型与我在ML、F、C等语言中看到的不兼容。例如,在F中,你可以通过
id
在ints上获取标识函数,这在这个模型中没有意义:id是一个值函数,不是返回值函数的类型函数



有类型理论知识的人能解释什么是forall和存在吗?“forall在类型级别上是lambda”在多大程度上是正确的?让我分别回答您的问题

  • 调用forall“类型级别的lambda”是不准确的,原因有二。首先,它是lambda的类型,而不是lambda本身。其次,lambda存在于术语级别,即使它抽象了类型(类型级别的lambda也存在,它们提供了通常称为泛型类型的东西)

  • 通用量化并不一定意味着所有实例化的“相同行为”。这是一个称为“参数性”的特殊属性,可能存在也可能不存在。普通多态lambda演算是参数化的,因为您根本无法表达任何非参数行为。但是,如果您添加诸如typecase(又称内涵类型分析)之类的构造,或者将checked cast作为一种较弱的形式,那么您就失去了参数性。参数性意味着良好的属性,例如,它允许在没有任何类型的运行时表示的情况下实现语言。它归纳出非常强大的推理原理,例如,参见瓦德勒的论文《自由定理》。但这是一种折衷,有时您需要对类型进行调度

  • 存在类型本质上表示一个类型(所谓的见证)和一个术语(有时称为包)的对。一种常见的查看方法是作为抽象数据类型的实现。下面是一个简单的例子:

    包(Int,(λx.x,λx.x)):∃ T.(Int)→ T) ×(T→ Int)

    这是一个简单的ADT,它的表示形式是Int,并且只提供两个操作(作为嵌套元组),用于将Int转换为抽象类型T中的Int和抽象类型T中的Int。例如,这是模块类型理论的基础

  • 总之,通用量化提供客户端数据抽象,而存在类型双重提供实现端数据抽象

  • 作为补充说明,在所谓的lambda立方体中,forall和arrow被推广为∏型的统一概念(其中T1→T2=∏(x:T1)。T2和∀A.T=∏(A:&ast;).T),同样存在,并且元组可以推广到∑-类型(其中T1×T2=∑(x:T1)。T2和∃A.T=∑(A:&ast;).T)。这里是类型&ast;是“类型的类型”

如果forall是lambda…,那么存在什么

为什么,当然是元组

在中,有∏类型,对应于函数/通用量化,∑-类型,对应于元组/存在量化

它们的类型与您提出的非常相似(我在这里使用符号):

实际上,∏是一个无穷乘积,∑是一个无穷和。请注意,它们并不像您所建议的那样是“相交”和“并集”,因为如果不另外定义类型相交的位置,就无法做到这一点。(一种类型的哪些值对应于另一种类型的哪些值)

从这两个类型构造函数中,您可以拥有所有正常、多态和依赖函数、正常和依赖元组,以及存在和普遍量化的语句:

-- Normal function, corresponding to "Integer -> Integer" in Haskell
factorial : Π ℕ (λ _ → ℕ)

-- Polymorphic function corresponding to "forall a . a -> a"
id : Π Set (λ A -> Π A (λ _ → A))

-- A universally-quantified logical statement: all natural numbers n are equal to themselves
refl : Π ℕ (λ n → n ≡ n)


-- (Integer, Integer)
twoNats : Σ ℕ (λ _ → ℕ)

-- exists a. Show a => a
someShowable : Σ Set (λ A → Σ A (λ _ → Showable A))

-- There are prime numbers
aPrime : Σ ℕ IsPrime
然而,这根本不涉及参数性,而AFAIK参数性和Martin-Löf型理论是独立的


对于参数学,人们通常会参考。

几句话来补充这两个已经很好的答案

首先,不能说
forall
在类型级别上是lambda,因为在类型级别上已经有lambda的概念,它不同于
forall
。它出现在system F_omega中,是system F wi的扩展
forall(S,P) = P(S[0]) ∩ P(S[1]) ∩ P(S[2]) ...
exists(S,P) = P(S[0]) ∪ P(S[1]) ∪ P(S[2]) ...
forall, exists :: Set<T> -> (T -> Type) -> Type
forall(Types, t => (t -> t))
id :: forall T:Type. T -> T
id = (x => x)

id2 = id :: int -> int
Π : (A : Set) -> (A -> Set) -> Set
Σ : (A : Set) -> (A -> Set) -> Set
-- Normal function, corresponding to "Integer -> Integer" in Haskell
factorial : Π ℕ (λ _ → ℕ)

-- Polymorphic function corresponding to "forall a . a -> a"
id : Π Set (λ A -> Π A (λ _ → A))

-- A universally-quantified logical statement: all natural numbers n are equal to themselves
refl : Π ℕ (λ n → n ≡ n)


-- (Integer, Integer)
twoNats : Σ ℕ (λ _ → ℕ)

-- exists a. Show a => a
someShowable : Σ Set (λ A → Σ A (λ _ → Showable A))

-- There are prime numbers
aPrime : Σ ℕ IsPrime
type prod =
  lambda (a : *). lambda (b : *).
    forall (c : *). (a -> b -> c) -> c