我已经把所有的东西都简化到了最基本的部分,所以如果下面的示例代码是人为的,请耐心等待。假设我们有:
class Foo a where
foo :: a
data Type a = Type a
instance (Foo a) => Foo (Type a) where
foo = Type foo
现在,假设我想
Type a
例如,
Show
无论何时
a
是两者的一个实例
Foo
和
表演
(
表演
被选择以避免定义另一个类型类)。那我们想要什么
A型
成为
表演
?好吧,除非我们疯了,我们当然想让它像
instance (Foo a, Show a) => Show (Type a) where
show (Type x) = show x
或者可能
instance (Foo a, Show a) => Show (Type a) where
show (Type x) = "Blabla " ++ (show x)
很好,很好用。出于某种莫名其妙的原因,我们希望
show
输出任何
foo :: a
看起来/表演像!在我们做作的环境中,我无法想象我们为什么要这样做,但我们可以这么说。不应该
instance (Foo a, Show a) => Show (Type a) where
show _ = show foo
耍花招?
唉,GHC说
中的类型变量“a”不明确
约束:“foo a”[…]“show a”
也许GHC不知道
foo
我在说。我是说
foo :: Type a
或
foo::A
?将上一个代码段更改为
instance (Foo a, Show a) => Show (Type a) where
show _ = show (foo :: a)
给我
无法从中推断(foo a1)
上下文()
因在[…]使用“foo”而产生
可能的修复:
将(foo a1)添加到表达式类型签名的上下文中
在“show”的第一个参数中,即“(foo::a)”。
在表达式中:show(foo::a)
在这一点上,我开始认为我误解了一些基本的东西。然而,我有一种奇怪的感觉,过去类似的结构对我很有用。