Haskell 使用 GADT 的类型推断和类型变量的类型类约束

Haskell type inference with GADTs and typeclass constraints on type variables

我定义了一个自定义 GADT,其中类型构造函数对类型变量具有类型 class 约束,如下所示:

data MyGadt x where
  Sample :: Show a => a -> MyGadt a

现在,如果我定义以下两个函数:

foo (Sample a) = show a

bar a = Sample a

GHC 为它们推断类型让我有点恼火。 foo :: MyGadt x -> [Char] 没有提及 xShow 约束,而 bar :: Show a => a -> MyGadt a 确实需要明确提及约束。

我假设我不必提及约束,因为它是在 GADT 定义中声明的。 我唯一能想到的部分原因是 GADT 在函数中的位置。我不是很深入,但据我了解,MyGadtfoo 中处于正位置,在 bar 中处于负位置。

我什么时候必须明确提及类型 class 约束,GHC 什么时候根据 GADTs 类型构造函数的约束自行解决?

使用 GADT 的全部要点 您希望约束显示在 bar 的签名中,而不是 foo。如果你想要那个,那么你可以使用普通的旧 newtype 代替:

newtype MyAdt = Sample a

foo :: Show a => MyAdt a -> String
foo (Sample a) = show a

bar :: a -> MyAdt a
bar = Sample

foobar 中都有约束显然是行不通的,因为这样你就可以

showFunction :: (Integer -> Integer) -> String
showFunction = foo . bar