让我通过消除歧义消除一些混乱。我喜欢用价值水平的类比来解释这一点,因为人们往往更熟悉它。
类型构造函数是一种类型,您可以将其应用于类型参数以“构造”一个类型。
值构造函数是一个值,您可以将其应用于值参数以“构造”值。
值构造函数通常称为“函数”或“方法”。这些“构造函数”也被称为“多态的”(因为它们可用于构造变化的“形状”的“东西”)或“抽象”(因为它们抽象化了不同的多态实例之间的变化)。
在抽象/多态性的上下文中,一阶是指抽象的“单次使用”:您一次对某个类型进行了抽象,但是该类型本身无法对任何事物进行抽象。Java 5泛型是一阶的。
上述抽象特征的一阶解释是:
类型构造函数是一种类型,您可以将其应用于适当的类型参数以“构造”适当的类型。
值构造函数是一个值,您可以将其应用于适当的值参数以“构造”适当的值。
为了强调不涉及任何抽象(我想您可以称其为“零阶”,但我从未见过在任何地方使用过这种抽象),例如value 1
或type String
,我们通常说某种东西是“ proper”值或type。
适当的值在某种意义上是“立即可用的”,因为它不等待参数(它不会抽象化它们)。可以将它们视为可以轻松打印/检查的值(序列化功能就是作弊!)。
适当的类型是对值进行分类的类型(包括值构造函数),类型构造函数不对任何值进行分类(首先需要将它们应用于正确的类型参数以产生适当的类型)。要实例化一个类型,有必要(但不足以满足)是一个适当的类型。(它可能是抽象类,也可能是您无权访问的类。)
“高阶”只是一个通用术语,表示重复使用多态性/抽象。对于多态类型和值,这意味着同一件事。具体而言,高阶抽象是对某物的抽象,而某物是对某物的抽象。对于类型,术语“高级”是更通用的“高级”的专用版本。
因此,我们表征的高阶版本变为:
类型构造函数是一种类型,您可以将其应用于类型实参(适当的类型或类型构造函数)以“构造”适当的类型(构造函数)。
值构造函数是一个值,您可以将其应用于值参数(适当的值或值构造函数)以“构造”适当的值(构造函数)。
因此,“高阶”只是意味着当您说“抽象X”时,您的意思是真的!该X
被抽象在不失去自己的“抽象权利”:它可以抽象所有就是了。(顺便说一句,我在这里使用动词“抽象”是指:省略了对于值或类型的定义不是必不可少的东西,以便抽象的用户可以将其更改/提供为参数) )
以下是一些适当,一阶和高阶值和类型的示例(受Lutz的电子邮件启发):
proper first-order higher-order
values 10 (x: Int) => x (f: (Int => Int)) => f(10)
types (classes) String List Functor
types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ
使用的类定义为:
class String
class List[T]
class Functor[F[_]]
为了避免通过定义类进行间接操作,您需要以某种方式表示匿名类型的函数,这些函数在Scala中无法直接表达,但是您可以使用结构类型,而没有太多的语法开销(#λ
-style是由于https://stackoverflow.com / users / 160378 / retronym afaik):
在某些支持匿名类型函数的Scala假想未来版本中,您可以将示例的最后一行缩短为:
types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be
(就我个人而言,我很遗憾曾经谈论过“高类型类型”,毕竟它们只是类型!当您绝对需要消除歧义时,我建议您说“类型构造器参数”,“类型构造器成员” ,或“类型构造函数别名”,以强调您并不是在谈论适当的类型。)
ps:进一步使事情复杂化的是,“多态”以不同的方式模棱两可,因为多态类型有时表示通用的量化类型,例如Forall T, T => T
,这是适当的类型,因为它对多态值进行了分类(在Scala中,该值可以是写成结构类型{def apply[T](x: T): T = x}
)