Haskell ghc 7.8.2上的GADT和显式forall
我正在ghc 7.8.2上玩GADT和explicit forall。让我们看一下下面的简单示例:Haskell ghc 7.8.2上的GADT和显式forall,haskell,ghc,existential-type,gadt,Haskell,Ghc,Existential Type,Gadt,我正在ghc 7.8.2上玩GADT和explicit forall。让我们看一下下面的简单示例: {-# LANGUAGE GADTs, RankNTypes #-} data T1 a where T1 :: (b -> a) -> b -> T1 a data T2 a where T2 :: forall b. (b -> a) -> b -> T2 a 此处,ghc因以下原因而失效: Test.hs:7:26: Not in sco
{-# LANGUAGE GADTs, RankNTypes #-}
data T1 a where
T1 :: (b -> a) -> b -> T1 a
data T2 a where
T2 :: forall b. (b -> a) -> b -> T2 a
此处,ghc因以下原因而失效:
Test.hs:7:26: Not in scope: type variable ‘a’
Test.hs:7:35: Not in scope: type variable ‘a’
当注释掉T2
时,类型检查成功。
但是
T1
和T2
似乎是等价的。这是ghc中的错误还是GADT的某些限制?如果是后者,那么两者之间的区别是什么?我最初假设T1
中的a
构造函数绑定在数据T1 a
声明中。
但它实际上是在构造函数本身中隐式量化的。因此,
T2
构造函数是错误的,因为它显式地量化了b
,而没有量化a
我也遇到了类似的问题。根据chi的评论,我提出了以下解决方案:
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
data T2 :: * -> * where
T2 :: forall a b. (b -> a) -> b -> T2 a
我宁愿
b
与a
相比脱颖而出,但我想对于那些喜欢显式的人来说,包括我自己在内,这仍然比隐式要好。我认为这只是量化。编译器可能有一些规则,即使用显式或隐式量化,而不是两者的混合。顺便说一句,datat2a
中的a
不会向下延伸到构造函数;它的名字无关紧要。@luqui,这很奇怪。为什么a
在T1
的范围内而不在T2
的范围内?我只是不明白为什么显式量化会给它蒙上阴影。@projedi,因为T1使用隐式量化(所有变量都隐式地用于d),T2使用显式量化(而你没有量化a)@luqui啊,我明白了。因此T1
中的a
不绑定在data T1 a
上,而是隐式绑定在T1
构造函数上。谢谢的确出于这个原因,我有时更喜欢数据T1::*->*其中
,因为它没有命名其参数。