什么是类型系统背景下的"善良"?

Ash*_*ary 5 types scala

我已经阅读了维基百科的文章并搜索了明显的地方,但我被卡住了.有人可以简单地告诉我究竟是什么类型的?它是干什么用的 ?

Scala示例非常受欢迎

Jör*_*tag 8

简而言之:一种什么类型就是.

什么是价值1,2,3是价值观.那么,"Hello""World",truefalse,等等.

值属于类型.类型描述一组值.1,2并且3属于类型Nat,"Hello"并且"World"该类型Text,true并且false该类型Boolean.

函数将一个或多个值作为参数,并生成一个或多个值作为结果.为了有意义地对参数做一些事情,函数需要对它们做一些假设,这是通过约束它们的类型来完成的.因此,函数参数和返回值通常也有类型.

现在,函数也有一个类型,由其输入和输出的类型描述.例如,abs计算数字绝对值的函数具有类型

Number -> NonNegativeNumber
Run Code Online (Sandbox Code Playgroud)

add添加两个数字的功能具有类型

(Number, Number) -> Number
Run Code Online (Sandbox Code Playgroud)

该函数divmod具有类型

(Number, Number) -> (Number, Number)
Run Code Online (Sandbox Code Playgroud)

好的,但是如果函数将值作为参数并将值作为结果生成,并且函数是值,那么函数也可以将函数作为参数并将函数作为结果返回,对吧?这种功能的类型是什么?

假设我们有一个函数findCrossing可以找到一些其他函数(数字)与y轴相交的点.它将函数作为参数并作为结果产生一个数字:

(Number -> Number) -> Number
Run Code Online (Sandbox Code Playgroud)

或者是一个函数makeAdder,它产生一个函数,它接受一个数字并为其添加一个特定的数字:

Number -> (Number -> Number)
Run Code Online (Sandbox Code Playgroud)

并且计算另一个函数的导数的函数:

(Number -> Number) -> (Number -> Number)
Run Code Online (Sandbox Code Playgroud)

让我们看一下这里的抽象层次:价值是非常具体的.这只意味着一件事.如果我们在这里订购我们的抽象级别,我们可以说一个值的顺序为0.

一个函数,OTOH更抽象:单个函数可以产生许多不同的值.所以,它有订单1.

返回或接受函数的函数更加抽象:它可以产生许多不同的函数,这些函数可以产生许多不同的值.它有订单2.

通常,我们使用> 1" 更高阶 " 的订单调用所有内容.

好的,但那种呢?好了,我们上面提到1,2,"Hello",false等有型.但是什么类型的Number?还是Text?还是Boolean

嗯,它的类型Type当然是!这种"类型的类型"被称为一种.

就像我们可以拥有从值构造值的函数一样,我们可以使用从类型构造类型的函数.这些函数称为类型构造函数.

就像函数有类型一样,类型构造函数也有类型.例如,List类型构造函数采用元素类型并为该元素生成列表类型

Type -> Type
Run Code Online (Sandbox Code Playgroud)

Map类型的构造,需要一个密钥类型和值类型,并产生一个地图类型具有类

(Type, Type) -> Type
Run Code Online (Sandbox Code Playgroud)

现在,继续类比,如果我们可以使用函数作为参数,我们还可以使用类型构造函数将类型构造函数作为参数吗?当然!

一个例子是Functor类型构造函数.它需要一个类型构造函数并生成一个类型:

(Type -> Type) -> Type
Run Code Online (Sandbox Code Playgroud)

请注意我们总是写Type在这里?上面,我们有很多不同的类型,如Number,Text,Boolean等在这里,我们永远都只有一种类型,即Type.这对于(警告,前面的不良双关语)类型来说是乏味的,所以Type我们只是写作而不是到处写*.即Functor有那种

(* -> *) -> *
Run Code Online (Sandbox Code Playgroud)

并且Number有那种

*
Run Code Online (Sandbox Code Playgroud)

继续类比,Number,Text和类型的所有其他*有秩序0,List和类型的所有其他人* -> *或者更一般(*, …) -> (*, …)有1阶,Functor并且所有的样(* -> *) -> ** -> (* -> *)(等等)有秩序2.除在这种情况下,我们有时也把它叫做排名而不是订单.

超过顺序/等级1的所有内容称为高阶,高阶更高阶.

我希望这个比喻现在很明确:类型描述了价值观; 种类描述了各种类型.


旁白:我完全忽略了currying.基本上,currying意味着你可以将任何带有两个值的函数转换为一个函数,该函数接受一个值并返回一个取另一个值的函数,类似于三个,四个,五个......参数.这意味着您只需要使用一个参数来处理函数,这使得语言更加简单.

然而,这也意味着从技术上讲,它add是一个高阶函数(因为它返回一个函数),这使得定义变得混乱.


ped*_*rla 5

The most eloquent explanation for kinds/higher-kinds I've seen so far and also in the context of Scala is Daniel Spiewak's High Wizardry in the Land of Scala. There are many versions, he gave this talk a few times, here I've chosen the longest one, but you can quickly google and find others.

本次演讲中最重要的信息正是@Jörg W Mittag 给出的答案:

“种类之于类型就像类型之于价值”

关于该主题的更理论观点的另一个地方是论文Generics of a Higher Kind,也在 Scala 的上下文中。