我已经阅读了维基百科的文章并搜索了明显的地方,但我被困住了。有人可以简单地告诉我究竟是什么类型的?它用于什么?
Scala示例非常受欢迎
答案 0 :(得分:8)
简而言之:种类属于类型 类型属于值。
什么是值? 1
,2
,3
是值。 "Hello"
和"World"
,true
和false
也是如此,等等。
值属于类型。类型描述一组值。 1
,2
和3
属于类型Nat
,"Hello"
和"World"
类型Text
,{{1} }和true
到false
类型。
函数将一个或多个值作为参数,并生成一个或多个值作为结果。为了有意义地对参数做一些事情,函数需要对它们做一些假设,这是通过约束它们的类型来完成的。因此,函数参数和返回值通常也有类型。
现在,函数也有一个类型,由其输入和输出类型描述。例如,计算数字绝对值的Boolean
函数的类型为
abs
添加两个数字的函数Number -> NonNegativeNumber
的类型为
add
函数(Number, Number) -> Number
的类型为
divmod
好的,但是如果函数将值作为参数并将值作为结果生成,并且函数是值,那么函数也可以将函数作为参数并将函数作为结果返回,对吧?这种功能的类型是什么?
假设我们有一个函数(Number, Number) -> (Number, Number)
,它找到了一些其他函数(数字)穿过y轴的点。它将函数作为参数并生成一个数字:
findCrossing
或者是一个函数(Number -> Number) -> Number
,它产生一个函数,它接受一个数字并为其添加一个特定的数字:
makeAdder
计算另一个函数的导数的函数:
Number -> (Number -> Number)
让我们看看这里的抽象层次:价值是非常具体的。这只意味着一件事。如果我们在这里订购我们的抽象级别,我们可以说一个值的顺序为0。
一个函数,OTOH更抽象:单个函数可以产生许多不同的值。所以,它有1号订单。
返回或接受函数的函数更加抽象:它可以产生许多不同的函数,这些函数可以产生许多不同的值。它有2号订单。
一般情况下,我们通过订单调用所有内容> 1“更高阶”。
好的,但种怎么样?好吧,我们上面说(Number -> Number) -> (Number -> Number)
,1
,2
,"Hello"
等类型。但是false
的类型是什么?还是Number
?或Text
?
嗯,它的类型当然是Boolean
!这种“类型的类型”称为种类。
就像我们可以拥有从值构造值的函数一样,我们可以使用从类型构造类型的函数。这些函数称为类型构造函数。
就像函数有类型一样,类型构造函数也有类型。例如,Type
类型构造函数采用元素类型并为该元素生成列表类型具有类型
List
Type -> Type
类型构造函数,它采用键类型和值类型并生成地图类型具有种类
Map
现在,继续类比,如果我们可以使用函数作为参数,我们是否也可以使用类型构造函数将类型构造函数作为参数?当然!
一个例子是(Type, Type) -> Type
类型构造函数。它需要一个类型构造函数并生成一个类型:
Functor
注意我们总是在这里写(Type -> Type) -> Type
?上面,我们有许多不同的类型,例如Type
,Number
,Text
等。在这里,我们总是只有类型,即Boolean
。这对于(警告,前面的不良双关语)类型来说是乏味的,所以我们不是在任何地方写Type
,而是写Type
。即*
有类似的
Functor
和(* -> *) -> *
有种类
Number
继续比喻,*
,Number
和所有其他类型Text
的订单0,*
以及所有其他类型List
或更多* -> *
订单1 (*, …) -> (*, …)
,所有类型Functor
或(* -> *) -> *
(等等)都有订单2.除非在这种情况下,我们有时也会将其命名为等级而不是订单。
以上订单/等级1的所有内容都称为高阶,更高级别或更高级别。
我希望这个类比现在很明确:类型描述了价值观;种类描述了各种类型。
除此之外:我完全无视currying。基本上,currying意味着你可以将任何带有两个值的函数转换为一个函数,该函数接受一个值并返回一个取另一个值的函数,类似于三个,四个,五个......参数。这意味着您只需要使用一个参数来处理函数,这使语言更加简单。
然而,这也意味着从技术上讲,* -> (* -> *)
是一个高阶函数(因为它返回一个函数),这使得定义变得混乱。
答案 1 :(得分:4)
到目前为止,我在Scala的背景下看到的种类/更高种类的最有说服力的解释是Daniel Spiewak's High Wizardry in the Land of Scala。有很多版本,他几次给这个讲话,在这里我选择了最长的版本,但你可以快速google并找到其他版本。
本次演讲中最重要的信息正是@JörgWMittag给出的答案:
“kind是键入类型的值”
关于这个主题的更多理论观点的另一个地方是论文Generics of a Higher Kind,也是在Scala的背景下。