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

How to make a tuple with components belonging to a type class an instance

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

class Test a where
    elm :: a

知道元组我想做类似

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

(实际上,我想为向量空间对应的更花哨的类型class做类似的事情。)

这是怎么做到的?在此先感谢您的任何建议!

试试这个:

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 默认关闭是违反直觉的。