Haskell “什么是”呢;";在兰开佩斯
我理解Haskell “什么是”呢;";在兰开佩斯,haskell,polymorphism,higher-rank-types,Haskell,Polymorphism,Higher Rank Types,我理解如何帮助我们编写多态函数 根据这一点,我们通常编写的正规函数是秩1类型。该函数为秩2类型: foo :: (forall a. a -> a) -> (Char,Bool) foo f = (f 'c', f True) 它是这样解释的: 通常,秩n类型是至少有一个 秩-(n-1)参数,但没有更高秩的参数 等级论证到底是什么意思 有人能举一个与上述函数类似的秩3类型的例子吗。foo有一个参数,其中包括一个通用的量词,这就是需要RankN的原因。但是这个参数的类型本身,a->a
如何帮助我们编写多态函数
根据这一点,我们通常编写的正规函数是秩1类型。该函数为秩2类型:
foo :: (forall a. a -> a) -> (Char,Bool)
foo f = (f 'c', f True)
它是这样解释的:
通常,秩n类型是至少有一个
秩-(n-1)参数,但没有更高秩的参数
等级论证到底是什么意思
有人能举一个与上述函数类似的秩3类型的例子吗。foo
有一个参数,其中包括一个通用的量词,这就是需要RankN的原因。但是这个参数的类型本身,a->a
,是秩-1,它是唯一的参数,所以foo
的秩为n和n− 1=1,即foo
排名第二
现在考虑
bar :: ((forall a. a -> a) -> (Char,Bool)) -> Int
这有一个foo
类型的参数,正如我们所说的,它的级别为2。这是条
参数中的最高等级<因此,代码>栏是一个等级3的函数。n
是所有
的嵌套的级别。所以如果你对所有a都有。((a->a)->Bla)
(这是一种更为详细的编写(a->a)->Bla
)的方式),然后所有的位于外部,适用于整个函数,因此排名第一。使用(forall a.a->a)->Bla
时,forall
仅适用于内部函数(即您作为参数使用的函数),因此排名为2
如果作为参数的函数本身将另一个函数作为参数,并且该函数的类型中有一个forall
,那么这将是秩3。等等。等级是根据类型的结构归纳定义的:
rank (forall a. T) = max 1 (rank T)
rank (T -> U) = max (if rank T = 0 then 0 else rank T + 1) (rank U)
rank (a) = 0
注意在箭头的左侧它是如何增加1的。因此:
Rank 0: Int
Rank 1: forall a. a -> Int
Rank 2: (forall a. a -> Int) -> Int
Rank 3: ((forall a. a -> Int) -> Int) -> Int
等等。在罗伯特·哈珀的著作中,秩k
类型的定义是通过推理规则来说明的。根据这个定义,如果一个类型是秩k
,那么它也是秩k+1
。因此,一个类型与许多不同的等级k,k+1,k+2…
相关联,这意味着我们可以使用关系而不是函数进行形式化。假设Type
是所有类型的集合,N
是自然数的集合,S
是Type
和N
的笛卡尔积的期望子集。也就是说,S
的元素是表示“typeT
是秩n
”的元组(T,n)
。以下规则定义类型的列组
(a,0)
位于S
(T->U,0)
位于S
,如果(T,0)
和(U,0)
都位于S
(T->U,k+1)
位于S
,如果(T,k)
和(U,k+1)
都位于S
(T,k+1)
位于S
,如果(T,k)
位于S
(对于所有a.T,k+1)
位于S
,如果(T,k+1)
位于S
给定的(a,k)
位于S
根据上面的定义,你问题中的id
和foo
的类型分别是1,2,3…
和2,3,4…
。我认为这不太正确:例如fix:(a->a)->a
肯定是排名-1,不是秩2。为什么返回多态函数的函数不是秩2?这就是为什么在->
的左侧,而不是右侧,所有的排名都会增加的原因?为什么Int->(对于所有a.a->a)
不是排名2的类型?@leftaroundabout,你是对的,我修正了定义。@sepp2k,定义就是这样的。更深层次的原因是箭头的左边是负极,右边是正极。(这与顺序的定义类似。)@sepp2k:如果返回一个多态函数,这与整个多参数函数是(rank-1)多态函数一样,但类型变量恰好没有出现在第一个参数中。更准确地说,n
是所有
s嵌套在箭头左侧的级别(参见上的注释)。