【发布时间】:2012-09-02 12:55:03
【问题描述】:
我已经阅读了 Wikipedia 文章并搜索了明显的地方,但我被困住了。有人可以简单地告诉我 Kind 到底是什么吗?它是干什么用的?
Scala 示例最受赞赏
【问题讨论】:
标签: scala types higher-kinded-types type-constructor
我已经阅读了 Wikipedia 文章并搜索了明显的地方,但我被困住了。有人可以简单地告诉我 Kind 到底是什么吗?它是干什么用的?
Scala 示例最受赞赏
【问题讨论】:
标签: scala types higher-kinded-types type-constructor
简而言之:种类之于类型就像类型之于值。
什么是值? 1、2、3 是值。 "Hello" 和 "World"、true 和 false 也是如此。
值属于类型。类型描述了一组值。 1、2 和 3 属于类型 Nat、"Hello" 和 "World" 属于类型 Text、true 和 false 属于类型 Boolean。 >
函数将一个或多个值作为参数并产生一个或多个值作为结果。为了有意义地对参数做一些事情,函数需要对它们做出一些假设,这是通过约束它们的类型来完成的。所以,函数参数和返回值通常也有类型。
现在,一个函数也有一个类型,它由它的输入和输出的类型来描述。例如,计算数字绝对值的abs 函数的类型为
Number -> NonNegativeNumber
将两个数字相加的函数add具有类型
(Number, Number) -> Number
函数divmod有类型
(Number, Number) -> (Number, Number)
好的,但是如果函数将值作为参数并产生值作为结果,并且函数是值,那么函数也可以将函数作为参数并返回函数作为结果,对吧?这种函数的类型是什么?
假设我们有一个函数findCrossing,它可以找到一些其他函数(数字)穿过 y 轴的点。它将函数作为参数并生成一个数字:
(Number -> Number) -> Number
或者一个函数makeAdder,它产生一个函数,该函数接受一个数字并向其添加一个特定的数字:
Number -> (Number -> Number)
还有一个计算另一个函数导数的函数:
(Number -> Number) -> (Number -> Number)
让我们看看这里的抽象级别:值是非常具体的东西。它只意味着一件事。如果我们在这里对抽象级别进行排序,我们可以说一个值的顺序为 0。
一个函数,OTOH 更抽象:一个函数可以产生许多不同的值。所以,它的顺序是 1。
返回或接受函数的函数更加抽象:它可以产生许多不同的函数,这些函数可以产生许多不同的值。它有订单 2。
一般来说,我们称所有的顺序 > 1 "higher order"。
好的,但是种类呢?好吧,我们在上面说过1、2、"Hello"、false 等有类型。但是Number 的类型是什么?还是Text?还是Boolean?
嗯,它的类型当然是Type!这种“类型的类型”称为种类。
就像我们可以拥有从值构造值的函数一样,我们也可以拥有从类型构造类型的函数。这些函数称为类型构造函数。
就像函数有类型一样,类型构造函数也有种类。例如,List 类型构造函数,它接受一个元素类型并为该元素生成一个列表类型有 kind
Type -> Type
Map 类型构造函数,它接受一个键类型和一个值类型并产生一个映射类型有 kind
(Type, Type) -> Type
现在,继续类比,如果我们可以拥有将函数作为参数的函数,我们是否也可以拥有将类型构造函数作为参数的类型构造函数?当然!
一个例子是Functor 类型的构造函数。它接受一个类型构造函数并产生一个类型:
(Type -> Type) -> Type
注意到我们总是在这里写Type 吗?上面,我们有许多不同的类型,如Number、Text、Boolean 等。在这里,我们总是只有一种类型,即Type。这对(警告,坏双关语)类型来说很乏味,所以我们不用到处写Type,而是写*。 IE。 Functor有种
(* -> *) -> *
Number 有这种情况
*
继续类比,Number、Text 和所有其他同类 * 具有顺序 0、List 和所有其他同类 * -> * 或更一般地 (*, …) -> (*, …) 具有顺序 1、Functor并且所有类型的(* -> *) -> * 或* -> (* -> *)(等等)都具有顺序 2。除了在这种情况下,我们有时也将其称为 rank 而不是 order。
高于订单/等级 1 的所有内容都称为 higher-order、higher-rank 或 higher-kinded。
我希望这个类比现在很清楚了:类型描述了一组值;种类描述了类型的集合。
旁白:我完全忽略了柯里化。基本上,柯里化意味着您可以将任何接受两个值的函数转换为一个接受一个值并返回一个接受另一个值的函数,对于三个、四个、五个......参数也是如此。这意味着您只需要处理只有一个参数的函数,这使语言变得更加简单。
然而,这也意味着从技术上讲,add 是一个高阶函数(因为它返回一个函数),这混淆了定义。
【讨论】:
到目前为止,我在 Scala 的上下文中看到的关于种类/更高种类的最有说服力的解释是 Daniel Spiewak's High Wizardry in the Land of Scala。版本很多,他讲过几次,这里我选了最长的,不过大家可以快速google一下。
这次演讲最重要的信息正是@Jörg W Mittag 给出的答案:
“种类之于类型就像类型之于值”
另一个关于这个主题更理论观点的地方是论文Generics of a Higher Kind,也是在 Scala 的上下文中。
【讨论】: