我已将所有内容简化为基本内容,因此如果下面的示例代码是人为设计的,请耐心等待。假设我们有:
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
的一个实例和 Show
(选择 Show
是为了避免定义另一个类型类)。那么我们想要怎样Type a
成为 Show
的一个实例?好吧,除非我们疯了,我们当然希望它像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 说
Ambiguous type variable 'a' in the constraints: 'Foo a' [...] 'Show a'
也许 GHC 无法弄清楚是哪个
foo
我正在谈论。我的意思是 foo :: Type a
或 foo :: a
?将上一个片段更改为instance (Foo a, Show a) => Show (Type a) where
show _ = show (foo :: a)
给我
Could not deduce (Foo a1) from the context () arising from a use of 'foo' at [...] Possible fix: add (Foo a1) to the context of an expression type signature In the first argument of 'show', namely '(foo :: a)' In the expression: show (foo :: a)
在这一点上,我开始认为我误解了一些基本的东西。然而,我有一种奇怪的感觉,过去类似的结构对我有用。
最佳答案
我认为问题在于类型变量不限于定义。也就是说,在
instance (Foo a, Show a) => Show (Type a) where
show _ = show (foo :: a)
a
第二行不同于 a
在第一行,这就是为什么它显示为 a1
在错误消息中。见 http://www.haskell.org/haskellwiki/Scoped_type_variables .如果这是问题,这应该可以工作(我在这台机器上没有 GHC):asTypeOf :: a -> a -> a
asTypeOf a b = a
instance (Foo a, Show a) => Show (Type a) where
show (Type x) = show (foo `asTypeOf` x)
关于haskell - 使用常量值退化类型类实例声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4041111/