rank-n types上的haskell wiki页面告诉这种类型
forall a . a -> (forall b . b -> a)
有等级1。我相信这个事实,这对我来说似乎是可以理解的(牢记我已经知道如何确定功能等级的内容)。但是,当我尝试编写下一个代码时:
{-# LANGUAGE ExplicitForAll #-}
foo :: forall a . a -> (forall b . b -> a)
foo = undefined
它没有编译(GHC 8.0.1)导致下一个错误:
• Illegal polymorphic type: forall b. b -> a
Perhaps you intended to use RankNTypes or Rank2Types
• In the type signature:
foo :: forall a. a -> (forall b. b -> a)
所以我想知道: foo
类型真的有排名2吗?或GHC只是没有一些智能机制来检测功能的真实等级?有时,在教育目的中,我想拥有一些ghci
命令,例如rank
来检查功能类型的真实等级...
ghci> :rank foo
foo :: forall a . a -> (forall b . b -> a) -- Rank 1
在Typechecker的TcValidity
模块中记录了此行为的原因。
Note [Higher rank types]
~~~~~~~~~~~~~~~~~~~~~~~~
Technically
Int -> forall a. a->a
is still a rank-1 type, but it's not Haskell 98 (Trac #5957). So the
validity checker allow a forall after an arrow only if we allow it
before — that is, with Rank2Types or RankNTypes
我不是一个好的语言律师,但似乎Haskell 98规格似乎可以防止任何箭头之后的量词,尽管这比等级1'D-ness更为严格。由于Haskell 2010仅轻轻地更新了规格,我认为这也适用于2010年。
我相信(但不确定)GHC编码的方式是用checkValidType
函数中的let r1 = LimitedRank True r0
进行编码,该函数指定forall
S可以在类型声明的开头出现,但后续函数参数必须为零,该函数的参数必须排名零您类型中的forall b. b -> a
。
标准免责声明:我不是专家,我只有github搜索