我正在阅读斯卡拉学校的斯卡拉语言描述并且我不理解,并且无法在“一元类型”的任何地方找到参考文献"
以下是用法的上下文:
高级类型& ad-hoc多态性
[第2段]例如,“一元类型”具有构造函数 像List [A],意思是我们必须满足一个类型变量的“级别” 为了产生具体的类型(就像一个未经证实的功能 需要仅由一个要调用的参数列表提供),a 更高级的类型
来自https://twitter.github.io/scala_school/advanced-types.html#higher
由于
答案 0 :(得分:4)
这句话真的没有意义。
首先,没有“一元型”这样的东西。类型没有参数,因此没有意义。
是“一元类型构造函数”,即具有一个参数的类型构造函数,例如List[A]
。但该陈述暗示不是一元的所有类型构造函数都是高级的,而这根本不是真的。例如,Either[A, B]
是二进制(它有两个参数),但它不是更高的。
一个类型构造函数,其类型为构造函数作为其参数,或者类型构造函数返回类型构造函数作为其结果, 是一个更高通道的类型构造函数。就像具有两个参数的函数不是自动高阶的一样,只有具有函数参数或返回函数的函数是。 (注意:在一些数学分支中,函数被称为“值构造函数”,它实际上是名称“类型构造函数”的来源,因为就像函数接受值并生成值一样,类型构造函数接受类型并生成类型;类型构造函数类似于类型级别的函数。)
这里有一个皱纹,它与函数相同:当我们假设所有类型构造函数都是一元的时候,那么我们需要使用currying来表示具有多个参数的类型构造函数,并且在 意义上(并且仅在那个意义上!)所有非一元类型构造函数自动也是更高级的类型构造函数。同样,这就像函数一样:add
绝不是高阶函数,但如果我们使用currying,那么我们将它表示为一个函数,它接受一个整数并返回一个取第二个整数的函数返回一个整数,从技术上讲它是一个高阶函数。
但Scala中的情况并非如此:Scala 可以表示具有多个参数的类型构造函数,而不使用currying,因此非一元类型构造函数不会自动进行更高级的构造。
类似于类型的类型,除了我们简单地写*
而不是Type
,因为它不传达任何信息:类型构造函数总是对类型进行操作,不需要键入{{1}无处不在。因此,像Type
这样的一元类型构造函数具有类型:
List
像* → *
这样的二进制类型构造函数有:
Either
当您被迫使用currying表示它时,因为您的语言只允许单个类型参数,那么(*, *) → *
的类型将变为:
Either
您链接的网页中的* → * → * // `→` is right-associative just as with function types, so this is
* → (* → *) // which is higher-kinded
类型构造函数具有以下类型:
Container
因此,它将一个类型构造函数作为参数并返回一个类型。这就是使它更高的的原因。事实上,你会注意到Container :: (* → *) → *
实际上是一元的!它只需要一个参数。因此,该声明实际上包含了其自己的主张的反例。 (再次,这类似于函数。例如,Haskell前奏中的Container
函数是高阶的,但是一元:它只需要一个参数,但该参数是一个函数。)
在该描述中具体指出这一点的原因在于,对于诸如Java或C♯的类型OO语言领域中的某些其他主流语言,情况并非如此。 Java和C♯都不允许类型构造函数作为类型构造函数的参数或结果。您只能将类型传递给类型构造函数,类型构造函数的结果始终是类型。 Java和C♯都不支持更高级的类型。这使得Scala在这方面有些特别,这就是为什么在该页面上特别指出的原因。 (当然,在类型化函数语言领域,高知名度并不特别。)
tl; dr 摘要:
fix
Either[A] :: (*, *) → *
我的这个旧答案中有更多信息:What is a “kind” in the context of Type Systems?。
答案 1 :(得分:0)
一元是arity一个"的另一种说法。一个参数函数被认为是一元的,而两个参数函数是二元函数,三个是三元函数等等......
同样的原则适用于类型。例如,List[A]
或Set[A]
采用一种类型A
来形成新的正确类型,而Map[A, B]
采用两种类型,并且被称为二进制类型构造函数。
在旁注中,在类型构造函数上抽象的类型称为更高级的类型(例如:Monad[F[_]]
)