我有以下问题:我定义了一个类型类,并希望将此类的类型元组声明为实例。但我不知道如何让GHC接受这个声明。这是一个非常简单的例子:
class Test a where
elm :: a
知道元组我想做类似
的事情instance (Test a, Test b) => Test (a,b) where
elm = (elm, elm) :: (a,b)
(实际上,我想对与矢量空间相对应的更多花哨类型类做类似的事情。)
怎么做到这一点?提前感谢任何建议!
答案 0 :(得分:8)
请改为尝试:
instance (Test a, Test b) => Test (a,b) where
elm = (elm, elm)
这应该有效。您的代码问题是,您添加的:: (a,b)
类型注释实际上是混淆GHC而不是帮助它。问题是,当GHC看到a
和b
时,它认为它们代表了一些任意类型。但是你不希望它们是任意的,你希望它们与上面一行中引用的完全相同。但GHC并不知道这一点。如果保留类型注释,GHC将自己确定正确的类型。或者,您可以通过在文件顶部添加以下内容,启用ScopedTypeVariables
语言扩展来更改GHC的行为:
{-# LANGUAGE ScopedTypeVariables #-}
这将告诉GHC,只要有class
定义,顶行引用的类型变量将在其余定义的范围内。我是那些认为ScopedTypeVariables
默认情况应该处于开启状态的人之一,但不幸的是情况并非如此,主要是历史和&兼容性原因。实际上,这个问题提供了一个很好的论据,说明默认情况下ScopedTypeVariables
被禁用是违反直觉的。