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]
没有提及 x
的 Show
约束,而 bar :: Show a => a -> MyGadt a
确实需要明确提及约束。
我假设我不必提及约束,因为它是在 GADT 定义中声明的。
我唯一能想到的部分原因是 GADT 在函数中的位置。我不是很深入,但据我了解,MyGadt
在 foo
中处于正位置,在 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
在 foo
和 bar
中都有约束显然是行不通的,因为这样你就可以
showFunction :: (Integer -> Integer) -> String
showFunction = foo . bar
我定义了一个自定义 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]
没有提及 x
的 Show
约束,而 bar :: Show a => a -> MyGadt a
确实需要明确提及约束。
我假设我不必提及约束,因为它是在 GADT 定义中声明的。
我唯一能想到的部分原因是 GADT 在函数中的位置。我不是很深入,但据我了解,MyGadt
在 foo
中处于正位置,在 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
在 foo
和 bar
中都有约束显然是行不通的,因为这样你就可以
showFunction :: (Integer -> Integer) -> String
showFunction = foo . bar