如何使用属于类型类的组件作为实例来创建元组

时间:2016-09-15 20:14:50

标签: haskell ghc typeclass

我有以下问题:我定义了一个类型类,并希望将此类的类型元组声明为实例。但我不知道如何让GHC接受这个声明。这是一个非常简单的例子:

class Test a where
    elm :: a

知道元组我想做类似

的事情
instance (Test a, Test b) => Test (a,b) where
    elm = (elm, elm) :: (a,b)

(实际上,我想对与矢量空间相对应的更多花哨类型类做类似的事情。)

怎么做到这一点?提前感谢任何建议!

1 个答案:

答案 0 :(得分:8)

请改为尝试:

instance (Test a, Test b) => Test (a,b) where
    elm = (elm, elm)

这应该有效。您的代码问题是,您添加的:: (a,b)类型注释实际上是混淆GHC而不是帮助它。问题是,当GHC看到ab时,它认为它们代表了一些任意类型。但是你不希望它们是任意的,你希望它们与上面一行中引用的完全相同。但GHC并不知道这一点。如果保留类型注释,GHC将自己确定正确的类型。或者,您可以通过在文件顶部添加以下内容,启用ScopedTypeVariables语言扩展来更改GHC的行为:

{-# LANGUAGE ScopedTypeVariables #-}

这将告诉GHC,只要有class定义,顶行引用的类型变量将在其余定义的范围内。我是那些认为ScopedTypeVariables默认情况应该处于开启状态的人之一,但不幸的是情况并非如此,主要是历史和&兼容性原因。实际上,这个问题提供了一个很好的论据,说明默认情况下ScopedTypeVariables被禁用是违反直觉的。