繁体   English   中英

Scala 中的高级类型是什么?

[英]What is a higher kinded type in Scala?

您可以在 web 上找到以下内容:

  1. 高级类型 == 类型构造函数?

     class AClass[T]{...} // For example, class List[T]

    有人说这是一种高级类型,因为它抽象了符合定义的类型。

    更高种类的类型是采用其他类型并构造新类型的类型

    这些虽然也称为类型构造函数 (例如, 在 Scala 中的编程中)。

  2. 更高种类的类型 == 类型构造函数,它将类型构造函数作为类型参数?

    更高种类的论文 Generics 中,您可以阅读

    ...抽象类型的类型抽象类型('高级类型')......“

    这表明

    class XClass[M[T]]{...} // or trait YTrait[N[_]]{...} // eg trait Functor[F[_]]

    是高种类型。

因此,考虑到这一点,很难区分类型构造函数更高种类的类型以类型构造函数作为类型参数的类型构造函数,因此上面的问题。

让我通过一些消歧来弥补开始的一些混乱。 我喜欢用价值水平的类比来解释这一点,因为人们往往更熟悉它。

类型构造函数是可以应用于类型 arguments 以“构造”类型的类型。

值构造函数是可以应用于值 arguments 以“构造”值的值。

值构造函数通常称为“函数”或“方法”。 这些“构造函数”也被称为“多态”(因为它们可用于构造不同“形状”的“东西”)或“抽象”(因为它们抽象了不同多态实例之间的变化)。

在抽象/多态的上下文中,一阶是指抽象的“一次性使用”:您对一个类型进行一次抽象,但该类型本身不能对任何东西进行抽象。 Java 5 generics 为一阶。

上述抽象特征的一阶解释是:

类型构造函数是一种可以应用于正确类型 arguments 以“构造”正确类型的类型。

值构造函数是可以应用于正确值 arguments 以“构造”正确值的值。

为了强调不涉及抽象(我猜你可以称之为“零阶”,但我没有看到它在任何地方使用过),例如值1或类型String ,我们通常说某物是“正确”值或类型。

正确的值是“立即可用的”,因为它不等待 arguments(它不抽象它们)。 将它们视为您可以轻松打印/检查的值(序列化 function 是作弊。)。

正确的类型是对值进行分类的类型(包括值构造函数),类型构造函数不会对任何值进行分类(它们首先需要应用于正确的类型 arguments 以产生正确的类型)。 要实例化一个类型,有必要(但不充分)它是一个正确的类型。 (它可能是您无权访问的抽象 class 或 class。)

“高阶”只是一个通用术语,表示重复使用多态性/抽象。 对于多态类型和值来说,这意味着同样的事情。 具体来说,高阶抽象抽象了一些抽象的东西。 对于类型,术语“higher-kinded”是更一般的“higher-order”的特殊用途版本。

因此,我们表征的高阶版本变为:

类型构造函数是可以应用于类型 arguments(正确类型或类型构造函数)以“构造”正确类型(构造函数)的类型。

值构造函数是可以应用于值 arguments(正确值或值构造函数)以“构造”正确值(构造函数)的值。

因此,“高阶”仅仅意味着当你说“对 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 中无法直接表达,但您可以使用结构类型而不会产生太多语法开销( 样式是由于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} )

(这个答案试图通过一些图形和历史信息来装饰 Adriaan Moors 的答案。)

自 2.5 以来,更高种类的类型是 Scala 的一部分。

  • 在此之前 Scala 和 Java 之前不允许使用类型构造函数(Java 中的“泛型”)作为类型构造函数的类型参数。 例如

     trait Monad [M[_]]

    不可能。

    在 Scala 2.5 中,类型系统已通过在更高级别上对类型进行分类的能力进行了扩展(称为类型构造函数多态性)。 这些分类称为种类。

    类型和种类属性,**派生于**来自“更高种类的泛型” (图片来源于Generics of a Higher Kind

    结果是,该类型构造函数(例如List )可以与类型构造函数的类型参数 position 中的其他类型一样使用,因此它们成为自 Scala 2.5 以来的第一个 class 类型。 (类似于 Scala 中的第一个 class 值的函数)。

    在支持更高种类的类型系统的上下文中,我们可以区分正确的类型,如IntList[Int]等类型与List等一阶类型和更高类型的类型FunctorMonad (抽象的类型优于抽象的类型)超过类型)。

    另一边的 Java 的类型系统不支持种类,因此没有“更高种类”的类型。

    所以这必须在支持类型系统的背景下才能看到。

  • 在 Scala 的情况下,您经常会看到类型构造函数的示例,例如

     trait Iterable[A, Container[_]]

    标题为“更高类型的类型”,例如在Scala 中,用于通用程序员,第 4.3 节

    这有时会产生误导,因为许多人将Container称为更高种类的类型而不是Iterable ,但更准确的是,

    在这里使用Container作为更高种类(更高阶)类型的类型构造函数参数Iterable

IntChar这样的普通类型,其实例是值,是* Maybe这样的一元类型构造函数是* -> * Either这样的二进制类型构造函数有 ( curried ) kind * -> * -> *等等。 您可以将MaybeEither这样的类型视为类型级函数:它们采用一种或多种类型,并返回一个类型。

如果 function 的阶数大于 1,则它是高阶的,其中阶数(非正式地)是 function 箭头左侧的嵌套深度:

  • 订单 0: 1:: Int
  • 订单 1: chr:: Int -> Char
  • 订单 2: fix:: (a -> a) -> a , map:: (a -> b) -> [a] -> [b]
  • 订单 3: ((A -> B) -> C) -> D
  • 顺序 4: (((A -> B) -> C) -> D) -> E

所以,长话短说,更高种类的类型只是类型级别的更高阶 function抽象类型构造函数:

  • 订单 0: Int:: *
  • 订单 1: Maybe:: * -> *
  • 顺序 2: Functor:: (* -> *) -> Constraint —higher-kinded:将一元类型构造函数转换为类型类约束

我会说:更高种类的类型抽象了类型构造函数。 例如考虑

trait Functor [F[_]] {
   def map[A,B] (fn: A=>B)(fa: F[A]): F[B]
}

这里Functor是一种“更高种类的类型”(如“更高种类的泛型”论文中使用的那样)。 它不是像List那样的具体(“一阶”)类型构造函数(仅抽象适当的类型)。 它抽象了所有一元(“一阶”)类型构造函数(用F[_]表示)。

或者换一种说法:在 Java 中,我们有明确的类型构造函数(例如List<T> ),但是我们没有“更高种类的类型”,因为我们不能对它们进行抽象(例如,我们不能编写上面定义的Functor接口 - 至少不是直接的)。

术语“高阶(类型构造器)多态性”用于描述支持“更高种类的类型”的系统。

Scala REPL 提供:kind命令

scala> :help kind

:kind [-v] <type>
Displays the kind of a given type.

例如,

scala> trait Foo[A]
trait Foo

scala> trait Bar[F[_]]
trait Bar

scala> :kind -v Foo
Foo's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.

scala> :kind -v Foo[Int]
Foo[Int]'s kind is A
*
This is a proper type.

scala> :kind -v Bar
Bar's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type.

scala> :kind -v Bar[Foo]
Bar[Foo]'s kind is A
*
This is a proper type.

:help提供了清晰的定义,所以我认为值得在这里完整发布它(Scala 2.13.2)

scala> :help kind

:kind [-v] <type>
Displays the kind of a given type.

    -v      Displays verbose info.

"Kind" is a word used to classify types and type constructors
according to their level of abstractness.

Concrete, fully specified types such as `Int` and `Option[Int]`
are called "proper types" and denoted as `A` using Scala
notation, or with the `*` symbol.

    scala> :kind Option[Int]
    Option[Int]'s kind is A

In the above, `Option` is an example of a first-order type
constructor, which is denoted as `F[A]` using Scala notation, or
* -> * using the star notation. `:kind` also includes variance
information in its output, so if we ask for the kind of `Option`,
we actually see `F[+A]`:

    scala> :k -v Option
    Option's kind is F[+A]
    * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.

When you have more complicated types, `:kind` can be used to find
out what you need to pass in.

    scala> trait ~>[-F1[_], +F2[_]] {}
    scala> :kind ~>
    ~>'s kind is X[-F1[A1],+F2[A2]]

This shows that `~>` accepts something of `F[A]` kind, such as
`List` or `Vector`. It's an example of a type constructor that
abstracts over type constructors, also known as a higher-order
type constructor or a higher-kinded type.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM