假设我定义了一个类型
data A a = A a | B deriving Show
我知道(B :: A Int) == (B :: A Double)
不进行类型检查,因为A Int
和A Double
是不同的、不相等的类型,所以我不能应用(==) :: Eq a => a -> a -> Bool
但我可以问ghci什么是show B
,ghci说它是字符串"B"。B
究竟是什么类型的?是A Int
吗?为什么?为什么ghci不抱怨B
的类型是模糊的,因为它绝对可以是任何a
的A a
。
我可以类似地问ghci什么是show (B==B)
,它说"是",这两个B
的类型是什么?
当我用:t B
询问ghci B的类型时,它会打印B :: A a
,但除非我在上面的两个例子中感到困惑,否则它必须是一些特定于的类型,没有任何类型参数。那么,我该如何找出B==B
中B
的类型呢?
我有点困惑。这里有描述吗?
行为的原因是一个名为ExtendedDefaultRules的ghc扩展。
从链接引用:
然而,用户必须指定类型是令人厌烦的,因此GHCi扩展了Haskell的类型默认规则(Haskell 2010年报告)如下。标准规则将每组每个类型变量a的约束(C1a,C2a,…,Cn-a),以及如果,则默认类型变量
- 类型变量a不显示在其他约束中
- 所有的类Ci都是标准的
- 类Ci中的至少一个是数字
在GHCi提示下,如果-XExtendedDefaultRules标志为给定,以下附加差异适用:
- 因此,上述规则2被放宽:所有类Ci都是单参数类型类
- 上述规则3放宽如下:至少有一个类Ci是数字,或者是Show、Eq或Ord。单元类型()添加到标准类型列表的开头在执行类型默认时尝试
因此,根据这些规则,在B == B
或show B
中,()
被选作a
。
您也可以通过在GHCi提示下执行以下操作来测试这一点:
:set -XNoExtendedDefaultRules
data Foo a = A a | B deriving Eq
B == B
这导致了预期的CCD_ 21误差。