Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell ghc 7.8.2上的GADT和显式forall_Haskell_Ghc_Existential Type_Gadt - Fatal编程技术网

Haskell ghc 7.8.2上的GADT和显式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

我正在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 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::*->*其中
,因为它没有命名其参数。