首页 文章

Scala - 什么是一元型?

提问于
浏览
1

我正在通过scala学校scala语言描述,我不明白,无法找到“一元型”的任何地方的参考

以下是用法的上下文:

高级类型和ad-hoc多态[第2段]例如,“一元类型”具有像List [A]这样的构造函数,这意味着我们必须满足一个“级别”的类型变量才能生成具体类型(就像一个未经证实的函数需要仅由一个要调用的参数列表提供),一个更高级的类型

来自https://twitter.github.io/scala_school/advanced-types.html#higher

谢谢

2 回答

  • 4

    那句话实际上没有意义 .

    首先,没有“一元型”这样的东西 . 类型没有参数,所以这没有意义 .

    存在“一元类型 constructors ”,即具有一个参数的类型构造函数,例如 List[A] . 但该陈述暗示所有不是一元的类型构造函数都是高级的,而这根本不是真的 . 例如, Either[A, B] 是二进制(它有两个参数),但它不是更高的 .

    一个类型构造函数,其类型为 constructor 作为其参数或类型构造函数,它返回一个类型 constructor 作为其结果,这是一个更高级的类型构造函数 . 就像具有两个参数的函数不是自动高阶的一样,只有具有函数参数或返回函数的函数是 . (注意:在一些数学分支中,函数被称为"value constructors",它实际上是名称"type constructor"的来源,因为就像函数接受值并生成值一样,类型构造函数接受类型并生成类型;类型构造函数是 - 类似于类型级别的函数 . )

    这里有一个皱纹,它与函数相同:当我们假设所有类型构造函数都是一元时,那么我们需要使用currying来表示具有多个参数的类型构造函数,并且在这个意义上(并且仅在那个中)感觉!)所有非一元类型构造函数自动也是更高级的类型构造函数 . 同样,这就像函数一样: add 绝不是高阶函数,但是如果我们使用currying,那么我们将它表示为一个函数,它接受一个整数并返回一个取第二个整数并返回一个整数的函数,这在技术上使它成为一个更高阶的功能 .

    但是Scala不是这样的:Scala可以表示具有多个参数的类型构造函数而不使用currying,因此非一元类型构造函数不会自动更高 .

    类似于类型的类型,除了我们简单地写 * 而不是 Type ,因为它不传达任何信息:类型构造函数总是对类型进行操作,不需要在任何地方键入 Type . 所以,像 List 这样的一元类型构造函数有:

    * → *
    

    Either 这样的二进制类型构造函数有:

    (*, *) → *
    

    当您被迫使用currying表示它时,因为您的语言只允许单个类型参数,那么 Either 的类型变为:

    * →  * → *  // `→` is right-associative just as with function types, so this is 
    * → (* → *) // which is higher-kinded
    

    您链接的页面中的 Container 类型构造函数具有以下类型:

    Container :: (* → *) → *
    

    因此,它将一个类型构造函数作为参数并返回一个类型 . 而这正是使它更高的原因 . 事实上,你会注意到 Container 实际上是一元的!它只需要一个参数 . 因此,该声明实际上包含了其自己的主张的反例 . (再次,这类似于函数 . 例如,Haskell前奏中的 fix 函数是高阶的,但是一元:它只需要一个参数,但该参数是一个函数 . )

    具体在该描述中指出这一点的原因是,对于诸如Java或C♯的类型OO语言领域中的某些其他主流语言,情况并非如此 . Java和C♯都不允许类型构造函数作为类型构造函数的参数或结果 . 您只能将类型传递给类型构造函数,类型构造函数的结果始终是类型 . Java和C♯都不支持更高级的类型 . 这使得Scala在这方面有些特别,这就是为什么在该页面上特别指出的原因 . (当然,在类型化函数语言领域,高知名度并不特别 . )

    tl;dr 摘要:

    • 没有"unary type"这样的东西

    • 语句将类型构造函数的arity(参数的数量)与更高的kindedness混淆(参数和/或结果是类型还是类型构造函数)

    • 非一元型构造函数不一定是高级的,例如, Either[A] :: (*, *) → *

    • 更高级的构造函数可以是一元的,例如 Container :: (* → *) → *


    我的这个旧答案还有更多信息:What is a “kind” in the context of Type Systems? .

  • 0

    一元是另一种说法“arity one” . 一个参数函数被认为是一元的,而两个参数函数是二元函数,三个是三元函数等等......

    同样的原则适用于类型 . 例如, List[A]Set[A] 采用一种类型 A 来形成一个新的正确类型,而 Map[A, B] 采用两种,并且被称为二进制类型构造函数 .

    另外,在类型构造函数上抽象的类型称为更高级的类型(例如: Monad[F[_]]

相关问题