我正在通过scala学校scala语言描述,我不明白,无法找到“一元型”的任何地方的参考
以下是用法的上下文:
高级类型和ad-hoc多态[第2段]例如,“一元类型”具有像List [A]这样的构造函数,这意味着我们必须满足一个“级别”的类型变量才能生成具体类型(就像一个未经证实的函数需要仅由一个要调用的参数列表提供),一个更高级的类型
来自https://twitter.github.io/scala_school/advanced-types.html#higher
谢谢
我正在通过scala学校scala语言描述,我不明白,无法找到“一元型”的任何地方的参考
以下是用法的上下文:
高级类型和ad-hoc多态[第2段]例如,“一元类型”具有像List [A]这样的构造函数,这意味着我们必须满足一个“级别”的类型变量才能生成具体类型(就像一个未经证实的函数需要仅由一个要调用的参数列表提供),一个更高级的类型
来自https://twitter.github.io/scala_school/advanced-types.html#higher
谢谢
2 回答
那句话实际上没有意义 .
首先,没有“一元型”这样的东西 . 类型没有参数,所以这没有意义 .
存在“一元类型 constructors ”,即具有一个参数的类型构造函数,例如
List[A]
. 但该陈述暗示所有不是一元的类型构造函数都是高级的,而这根本不是真的 . 例如,Either[A, B]
是二进制(它有两个参数),但它不是更高的 .一个类型构造函数,其类型为 constructor 作为其参数或类型构造函数,它返回一个类型 constructor 作为其结果,这是一个更高级的类型构造函数 . 就像具有两个参数的函数不是自动高阶的一样,只有具有函数参数或返回函数的函数是 . (注意:在一些数学分支中,函数被称为"value constructors",它实际上是名称"type constructor"的来源,因为就像函数接受值并生成值一样,类型构造函数接受类型并生成类型;类型构造函数是 - 类似于类型级别的函数 . )
这里有一个皱纹,它与函数相同:当我们假设所有类型构造函数都是一元时,那么我们需要使用currying来表示具有多个参数的类型构造函数,并且在这个意义上(并且仅在那个中)感觉!)所有非一元类型构造函数自动也是更高级的类型构造函数 . 同样,这就像函数一样:
add
绝不是高阶函数,但是如果我们使用currying,那么我们将它表示为一个函数,它接受一个整数并返回一个取第二个整数并返回一个整数的函数,这在技术上使它成为一个更高阶的功能 .但是Scala不是这样的:Scala可以表示具有多个参数的类型构造函数而不使用currying,因此非一元类型构造函数不会自动更高 .
类似于类型的类型,除了我们简单地写
*
而不是Type
,因为它不传达任何信息:类型构造函数总是对类型进行操作,不需要在任何地方键入Type
. 所以,像List
这样的一元类型构造函数有:像
Either
这样的二进制类型构造函数有:当您被迫使用currying表示它时,因为您的语言只允许单个类型参数,那么
Either
的类型变为:您链接的页面中的
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? .
一元是另一种说法“arity one” . 一个参数函数被认为是一元的,而两个参数函数是二元函数,三个是三元函数等等......
同样的原则适用于类型 . 例如,
List[A]
或Set[A]
采用一种类型A
来形成一个新的正确类型,而Map[A, B]
采用两种,并且被称为二进制类型构造函数 .另外,在类型构造函数上抽象的类型称为更高级的类型(例如:
Monad[F[_]]
)