如何在 haskell 中抓取类型 class 时普遍量化具体化类型 Class 实例?

how to universally quantify Reified Type Class instance when scraping your type class in haskell?

研究臭名昭著的博客postscrap your type classes, for the sake of learning, but in particular to understand the meaning of forall in type class instance declaration as stated here Explicit universal quantification (forall)

As well as in type signatures, you can also use an explicit forall in an instance declaration:

instance forall a. Eq a => Eq [a] where ...

这通常是我在 haskell 中完善我对 forall 的理解的背景,其中我学会了如何注意它的范围。

因此,为了明确起见,我一直在尝试为以下用例重现 scrap your type classes 方法:

data  DatumType a b = Datum a b deriving Show

instance forall a b . (Eq a, Eq b) => Eq (DatumType a b) where
  (==) (Datum x y) (Datum z e) =  x == z && y == e

将 Eq 重命名为 Same,即但声明为

data Same a = Same {
  (===) :: a -> a -> Bool
}

但是我被困在这里,因为我不知道如何用 forall a b 编写实例

SameDatumTypeab :: ???
SameDatumTypeab =  Same {
 -- ???
}

有人可以帮忙吗?这甚至可能吗?

没有什么是你无法通过反复试验想出的...

sameDatumTypeab :: ∀ a b . (Eq a, Eq b) => Same (DatumType a b)
sameDatumTypeab = Same {
   (===) = \(Datum x y) (Datum z e) -> x==z && y==e
 }

像往常一样,forall 是可选的(出现的变量在最外层隐式 universal-quantified),即您可以简单地写

sameDatumTypeab :: (Eq a, Eq b) => Same (DatumType a b)
sameDatumTypeab = Same $ \(Datum x y) (Datum z e) -> x==z && y==e

但实际上这有点遗漏了废弃你的 类 的要点,因为我现在 使用 Eq class 虽然我没有实例化它。为了使其完全 class-free,我们还想转换 (Eq a, Eq b) 约束:

sameDatumTypeab :: Same a -> Same b -> Same (DatumType a b)
sameDatumTypeab (Same eqa) (Same eqb)
   = Same $ \(Datum x y) (Datum z e) -> eqa x z && eqb y e

FTR,类型class实例也不需要显式量化

instance (Eq a, Eq b) => Eq (DatumType a b) where
  Datum x y == Datum z e = x == z && y == e