'Kind' 对类型索引的 GADT 中的 forall 感到困惑
'Kind' of confused about forall in type-indexed GADTs
我 运行 在 GHC 8.0.1 中遇到了一个奇怪的情况,使用种类索引(?)GADT,在类型与种类签名中引入 foralls 会产生不同的类型检查行为。
考虑以下数据类型:
{-# LANGUAGE TypeInType, GADTs, ExplicitForAll #-}
-- Same thing happens when we replace ExplicitForAll with ScopedTypeVariables
import Data.Kind
data F (k :: * -> *) where
data G :: F k -> * where
G :: G x
这种数据类型编译得很好。但是,如果我们想在构造函数G
中指定x
的种类,我们会得到一个类型错误。
data H :: F k -> * where
H :: forall k' (x :: F k'). H x
错误信息是
• Kind variable ‘k’ is implicitly bound in datatype
‘H’, but does not appear as the kind of any
of its type variables. Perhaps you meant
to bind it (with TypeInType) explicitly somewhere?
• In the data declaration for ‘H’
如果我们将forall
添加到kind签名中(在构造函数中有或没有forall
),没有错误。
data I :: forall k. F k -> * where
I :: I x
data J :: forall k. F k -> * where
J :: forall k' (x :: F k'). J x
怎么回事?
TypeInType
的作者在这里。 K. A. Buhr 就在上面得到了它;这只是一个错误。它固定在 HEAD 中。
对于过度好奇的人:此错误消息旨在消除像
这样的定义
data J = forall (a :: k). MkJ (Proxy a)
哪里
data Proxy (a :: k) = Proxy
可以从 Data.Proxy
导入。当在 Haskell98 风格的语法中声明一个数据类型时,任何存在量化的变量都必须用 forall
显式地引入范围。但是 k
从来没有明确地进入范围;只是用在a
的那种。所以这意味着 k
应该被普遍量化(换句话说,它应该是 J
的不可见参数,就像 Proxy
的 k
参数一样)......但是那么当我们写J
的时候,就没有办法确定k
应该是什么,所以总是模棱两可的。 (相比之下,我们可以通过查看 a
的类型来发现 k
参数到 Proxy
的选择。)
此 J
的定义在 8.0.1 和 HEAD 中是不允许的。
我 运行 在 GHC 8.0.1 中遇到了一个奇怪的情况,使用种类索引(?)GADT,在类型与种类签名中引入 foralls 会产生不同的类型检查行为。
考虑以下数据类型:
{-# LANGUAGE TypeInType, GADTs, ExplicitForAll #-}
-- Same thing happens when we replace ExplicitForAll with ScopedTypeVariables
import Data.Kind
data F (k :: * -> *) where
data G :: F k -> * where
G :: G x
这种数据类型编译得很好。但是,如果我们想在构造函数G
中指定x
的种类,我们会得到一个类型错误。
data H :: F k -> * where
H :: forall k' (x :: F k'). H x
错误信息是
• Kind variable ‘k’ is implicitly bound in datatype ‘H’, but does not appear as the kind of any of its type variables. Perhaps you meant to bind it (with TypeInType) explicitly somewhere? • In the data declaration for ‘H’
如果我们将forall
添加到kind签名中(在构造函数中有或没有forall
),没有错误。
data I :: forall k. F k -> * where
I :: I x
data J :: forall k. F k -> * where
J :: forall k' (x :: F k'). J x
怎么回事?
TypeInType
的作者在这里。 K. A. Buhr 就在上面得到了它;这只是一个错误。它固定在 HEAD 中。
对于过度好奇的人:此错误消息旨在消除像
这样的定义data J = forall (a :: k). MkJ (Proxy a)
哪里
data Proxy (a :: k) = Proxy
可以从 Data.Proxy
导入。当在 Haskell98 风格的语法中声明一个数据类型时,任何存在量化的变量都必须用 forall
显式地引入范围。但是 k
从来没有明确地进入范围;只是用在a
的那种。所以这意味着 k
应该被普遍量化(换句话说,它应该是 J
的不可见参数,就像 Proxy
的 k
参数一样)......但是那么当我们写J
的时候,就没有办法确定k
应该是什么,所以总是模棱两可的。 (相比之下,我们可以通过查看 a
的类型来发现 k
参数到 Proxy
的选择。)
此 J
的定义在 8.0.1 和 HEAD 中是不允许的。