首页 文章

使用常量值退化类型类实例声明

提问于
浏览
4

我已将所有内容减少到必需品,所以如果下面的示例代码是设计的,请耐心等待 . 假设我们有:

class Foo a where
    foo :: a

data Type a = Type a

instance (Foo a) => Foo (Type a) where
    foo = Type foo

现在,假设我想让 Type aShow 的实例,只要 aFooShow 的实例(选择 Show 以避免定义另一个类型类) . 那么我们如何让 Type a 成为 Show 的一个实例呢?好吧,除非我们're crazy, we'当然希望它是这样的

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)

's all great and works fine. For some inexplicable reason, we'喜欢 show 输出 foo :: a 看起来/显示的东西!在我们设计的环境中,我无法想象为什么我们会这样做 . 不能

instance (Foo a, Show a) => Show (Type a) where
    show _ = show foo

做诀窍?

唉,GHC说

约束中的模糊类型变量'a':'Foo 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)

在这一点上,我开始认为我误解了一些基本的东西 . 然而,我有一种奇怪的感觉,过去类似的结构对我有用 .

1 回答

  • 6

    我认为问题是类型变量没有作用于定义 . 也就是说,在

    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)
    

相关问题