具有RankNTypes扩展名的奇怪类型推断

时间:2014-05-08 04:19:05

标签: haskell ghc

我正在尝试在Haskell中试验System-F类型,并通过type实现了自然数的Church编码。

加载此代码时

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE RankNTypes #-}

type CNat = forall t . (t -> t) -> (t -> t)

c0 :: CNat
c0 _ x = x

type CPair a b = forall t . (a -> b -> t) -> t

cpair :: a -> b -> CPair a b
cpair a b f = f a b

-- pair3 :: CPair CNat String
pair3 = cpair c0 "hello"

进入ghci 7.8.2我收到警告:

λ: :l test.hs 
[1 of 1] Compiling Main             ( test.hs, interpreted )

test.hs:29:1: Warning:
    Top-level binding with no type signature:
      pair3 :: forall t t1.
               (((t1 -> t1) -> t1 -> t1) -> [Char] -> t) -> t
Ok, modules loaded: Main.
λ: 

问题是,不应该是

类型
pair3 :: forall t.
      ((forall t1. (t1 -> t1) -> t1 -> t1) -> [Char] -> t) -> t

UPD:提供了一个更简单的示例

2 个答案:

答案 0 :(得分:10)

这对它来说是一个非常好的类型......但它不是Hindley-Milner给它的类型。 HM 始终推断排名-1类型。我相信,推断排名2类型实际上是可判定的,但GHC甚至不会尝试。

答案 1 :(得分:4)

  

但有没有办法为它指定我的类型   我明确指定它(取消注释我的代码中的行),编译器   不会推断它,但只是检查提供的类型?现在我来了   错误

如果要实例化a,b类型中出现的类型变量cpair,可以添加以下显式注释。

pair3 :: CPair CNat String
pair3 = (cpair :: CNat -> String -> CPair CNat String) c0 "hello"

如果没有这个,我相信cpair只在单态类型中实例化。