1

Haskell wiki page on Rank-N-Types 告诉这个类型

forall a . a -> (forall b . b -> a)

排名第一。我相信这个事实,这对我来说似乎很容易理解(记住我已经知道如何确定函数的排名)。但是,当我尝试编写下一个代码时:

{-# 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类型真的有Rank-2吗?或者 GHC 只是没有一些智能机制来检测真正的功能等级?有时出于教育目的,我想要一些ghci命令,例如rank检查函数类型的真实等级......

ghci> :rank foo
foo :: forall a . a -> (forall b . b -> a)  -- Rank 1
4

1 回答 1

3

这种行为的原因记录在类型检查器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 规范似乎阻止了任何箭头后的量词,尽管这是一个比 rank-1'd-ness 更严格的要求。由于 Haskell 2010 仅对规范进行了轻微更新,我相信这也适用于 2010。

我相信(但不确定)GHC 编码的方式是let r1 = LimitedRank True r0checkValidType函数中使用 a ,它指定foralls 可以出现在类型声明的开头,但后续函数参数必须为零,这排除了forall b. b -> a你的类型。

标准免责声明:我不是专家,我所拥有的只是 github 搜索

于 2016-12-18T18:12:42.987 回答