类型理论中的正确术语:类型,类型构造函数,种类/排序和值


14

在回答前一个问题时,围绕特定结构的正确术语展开了一场小型辩论。由于我没有找到一个清楚地解决这个问题的问题(除了thisthat,那不是很正确的事情),因此我正在提出一个新的问题。

可疑的术语及其关系是:类型,类型构造函数,类型参数,种类或种类以及值

我还检查了维基百科上的类型理论,但这也没有太多说明。

因此,为了获得良好的参考答案并检查我自己的理解:

  • 这些东西如何正确定义?
  • 这些东西之间有什么区别?
  • 它们如何相互关联?

Answers:


13

好吧,让我们一个接一个地走。

价值观

值是程序评估和处理的具体数据。没什么好看的,有些例子可能是

  • 1
  • true
  • "fizz buzz foo bar"

种类

对类型的一个很好的描述是“值的分类器”。类型是关于在运行时该值将是什么的一点信息,但是在编译时指示。

例如,如果你告诉我,e : bool在编译的时候,我就知道,e要么是truefalse运行期间,没有别的!因为类型可以很好地对值进行分类,所以我们可以使用此信息来确定程序的一些基本属性。

例如,如果我看到您添加e以及e'何时e : inte' : String,那么我知道有些问题了!实际上,我可以对此进行标记并在编译时抛出错误,说:“嘿,那根本没有任何意义!”。

功能更强大的类型系统允许分类更多有趣值的更多有趣类型。例如,让我们考虑一些功能

f = fun x -> x

很显然f : Something -> Something,但是那应该Something是什么?在无聊的类型系统中,我们必须指定任意内容,例如Something = int。在更灵活的类型系统中,我们可以说

f : forall a. a -> a

就是说“对于任何a,都f将一个映射aa”。这让我们f更广泛地使用并编写更多有趣的程序。

而且,编译器将检查实际上是否满足我们给定的分类器,如果f = fun x -> true存在错误,编译器会说!

因此,作为一个tldr;类型是对表达式在运行时可能具有的值的编译时约束。

类型构造器

一些类型是相关的。例如,整数列表与字符串列表非常相似。这几乎就像sort整数如何像sort字符串一样。我们可以想象出一种工厂,通过概括它们之间的差异并根据需要构建它们,从而构建这些几乎相同的类型。这就是类型构造函数。它有点像从类型到类型的函数,但有更多限制。

经典示例是通用列表。类型构造器只是通用定义

 data List a = Cons a (List a) | Nil

现在List是一个将类型映射a到该类型的值列表的函数!在Java领域,我认为这些可能称为“泛型类”

类型参数

类型参数只是传递给类型构造函数(或函数)的类型。就像在值级别中一样,我们要说foo(a)有一个参数a,就像List a有类型参数一样a

种类

种类有点棘手。基本思想是某些类型是相似的。例如,我们在java int,...中都有所有原始类型charfloat它们的行为都好像它们具有相同的“类型”。例外,当我们谈论类型本身的分类器时,我们将分类器称为种。所以int : PrimString : BoxList : Boxed -> Boxed

该系统给出了关于可以在哪里使用哪种类型的好规则,就像类型如何控制值一样。说显然是胡说八道

 List<List>

要么

 List<int>

在Java中,List需要像这样使用一个具体的类型!如果我们看一下它们的种类List : Boxed -> Boxed,因为Boxed -> Boxed /= Boxed,以上是一种错误!

大多数时候,我们并不是真正地考虑种类,而只是将它们视为“常识”,但是对于更高级的类型系统来说,思考是很重要的。

到目前为止,我一直在说些什么

 value   : type : kind  : ...
 true    : bool : Prim  : ...
 new F() : Foo  : Boxed : ...

比维基百科更好的阅读

如果您对这种事情感兴趣,我强烈建议您投资购买一本好教科书。一般而言,类型理论和PLT非常广泛,并且没有(或至少我)一个连贯的知识基础,您就可以在几个月之内流连忘返。

我最喜欢的两本书是

  • 类型和编程语言-Ben Pierce
  • 编程语言的实践基础-Bob Harper

这两本书都是出色的书,介绍了我刚刚谈论的内容,并且以美丽,详尽的细节进行了介绍。


1
类型是集合?我更喜欢“分类器”,但是您不解释这意味着什么,并且如果不充分了解类型是什么,答案的其余部分就会下降。
罗伯特·哈维

@RobertHarvey现在看起来如何,我删除了所有关于布景的信息:)
Daniel Gratzer 2014年

1
好多
罗伯特·哈维

@RobertHarvey我发现集合的类型视图非常直观。例如int,Java中的类型由一组2 ^ 64个不同的值组成。与子集的类比在涉及子类型时会中断,但这是足够好的初始直觉,尤其是在考虑代数数据类型后(例如,两种类型的并集可以包含任何一种类型的成员;这是那些集的并集) 。
2014年

@Doval:如果我编写一个描述Customer的类,则可能要代表一组“客户”,因为我要收集实例。但是说客户是类型是因为它描述了客户的“集合”,这是一种重言式。似乎很明显。更有趣的是,客户类型描述了客户的特征。用“ set”来解释这一点似乎比实际要抽象得多。除非,也许你是数学家。
罗伯特·哈维

2

这些东西如何正确定义?

它们由严格的学术数学支持正确地定义,就它们是什么,它们如何工作以及可以保证什么提供了有力的断言。

但是程序员基本上不需要知道这一点。他们需要了解概念。

价值观

让我们从价值开始,因为一切都是从那里建立的。值是计算中使用的数据。根据方法的不同,它们是每个人都熟悉的价值观:42、3.14,“如何现在变成棕色母牛”,Jenny down在Accounting中的人事记录等。

值的其他解释是符号。大多数程序员将这些符号理解为枚举的“值”。LeftRight是枚举的符号Handedness(忽略灵巧的人和鱼)。

无论采用何种实现方式,值都是语言在执行计算时所要使用的不同内容。

种类

值的问题在于,并非所有计算对于所有值都是合法的。42 + goat根本没有道理。

这就是类型发挥作用的地方。类型是定义值子集的元数据。Handedness上面的枚举是一个很好的例子。此类型表示“仅Left并且Right可以在此处使用”。这使程序可以很早地确定某些操作将导致错误。

需要考虑的另一个实际用途是,在后台,计算机使用字节进行工作。字节42可能意味着数字42,或者可能意味着字符*,或者可能意味着Accounting的Jenny。类型(在实际使用中,理论上也没那么多)有助于定义计算机使用的底层字节集的编码。

种类

这是我们开始进行一些尝试的地方。那么,当一种编程语言的变量引用一个类型时,具有什么类型?

例如,在Java和C#中,它具有类型Type(具有类型Type,具有...依此类推)。这是种类背后的概念。在某些语言中,使用Type变量可以比Java和C#做更多有用的事情。一旦出现这种情况可以说成为有用的“我要的值是一个类型,但也有一些样的IEnumerable<int>”。- 种。

大多数程序员可以想到类似Java和C#通用约束的类型。考虑一下public class Foo<T> where T: IComparable{}。在多种语言中,T: kindOf(IComparable)变量声明变得合法;您不仅可以在类和函数声明中执行特殊操作。

类型构造器

也许并不奇怪,类型构造函数只是类型的构造函数。“但你如何构建一个类型?类型只是。” 嗯...没那么多。

同样也不足为奇的是,构建任何计算机程序都将使用的所有不同的有用值子集非常困难。类型构造函数有助于程序员以有意义的方式“构建”那些子集。

类型构造函数最普遍的示例是数组定义:int[4]。在这里,您要指定4类型构造函数,该构造函数使用该值为您构建一个int包含4个条目的s 数组。如果您指定了其他输入类型,则将获得其他输出类型。

泛型是类型构造函数的另一种形式,采用另一种类型作为其输入。

在许多语言中,有一个类型构造函数,例如P -> R要构建一个表示表示采用type P并返回type 的函数的类型R

现在,上下文将确定“返回类型的函数”是否为类型构造函数。根据我的经验(有限),这一行是“您可以在编译时使用此类型吗?”。是?类型构造函数。没有?只是一个功能。

类型参数

您还记得传递给类型构造函数的参数吗?它们通常称为类型参数,因为类型构造函数的常见形式是Type[param]Type<param>


1
您能否澄清/扩展有关“种类”的部分?在Haskell中,类型具有kind *,而类型构造函数(带有一个参数)具有kind * -> *。诸如(Num a) => a(表示“ 作为类型类a实例的任何Num类型”)的约束本身并不是种类。类型类Num本身不是“种类”,但具有种类* -> Constraint。我发现很难将Haskell的“种类”(我认为与类型理论中的种类紧密相关?)的思想与您给出的例子联系起来。
John Bartholomew 2014年

我应该说,ghci的:kind命令给出了Numas 的种类* -> Constraint。我不知道那可能是GHC特有的。
John Bartholomew 2014年

@JohnBartholomew-Haskell种类更多的是“类型构造函数的签名”。不幸的是,我的Haskell并没有到我愿意谈论太多细节的地步。
Telastyn 2014年
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.