在haskell中,没有参数的ADT的构造函数的类型究竟是什么



假设我定义了一个类型

data A a = A a | B deriving Show

我知道(B :: A Int) == (B :: A Double)不进行类型检查,因为A IntA Double是不同的、不相等的类型,所以我不能应用(==) :: Eq a => a -> a -> Bool

但我可以问ghci什么是show B,ghci说它是字符串"B"。B究竟是什么类型的?是A Int吗?为什么?为什么ghci不抱怨B的类型是模糊的,因为它绝对可以是任何aA a

我可以类似地问ghci什么是show (B==B),它说"是",这两个B的类型是什么?

当我用:t B询问ghci B的类型时,它会打印B :: A a,但除非我在上面的两个例子中感到困惑,否则它必须是一些特定于类型,没有任何类型参数。那么,我该如何找出B==BB的类型呢?

我有点困惑。这里有描述吗?

行为的原因是一个名为ExtendedDefaultRules的ghc扩展。

从链接引用:

然而,用户必须指定类型是令人厌烦的,因此GHCi扩展了Haskell的类型默认规则(Haskell 2010年报告)如下。标准规则将每组每个类型变量a的约束(C1a,C2a,…,Cn-a),以及如果,则默认类型变量

  1. 类型变量a不显示在其他约束中
  2. 所有的类Ci都是标准的
  3. 类Ci中的至少一个是数字

在GHCi提示下,如果-XExtendedDefaultRules标志为给定,以下附加差异适用:

  • 因此,上述规则2被放宽:所有类Ci都是单参数类型类
  • 上述规则3放宽如下:至少有一个类Ci是数字,或者是Show、Eq或Ord。单元类型()添加到标准类型列表的开头在执行类型默认时尝试

因此,根据这些规则,在B == Bshow B中,()被选作a

您也可以通过在GHCi提示下执行以下操作来测试这一点:

:set -XNoExtendedDefaultRules
data Foo a = A a | B deriving Eq
B == B

这导致了预期的CCD_ 21误差。

最新更新