这是几分钟前刚刚提出的问题的修改 - 但是对于这种情况我遇到了问题......
我有以下问题:我定义了一个类型类,并希望将此类的类型元组声明为实例。但我不知道如何让GHC接受这个声明。这是一个非常简单的例子:
class Test x a where
elm :: a
知道元组我想做类似
的事情instance (Test x a, Test x b) => Test x (a,b) where
elm = (elm, elm)
此外,我正在使用
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
添加类型x
会导致麻烦......
怎么做到这一点?提前感谢任何建议!
答案 0 :(得分:3)
这与元组没有任何关系。问题只是x
出现在班主任中,而不是elm
的签名 - 所以当x
时无法确定要用作elm
类型的内容在代码中的某处出现。
的确,如果elm
是Test
的唯一方法,则根本不需要x
参数 - 只需删除它,您的实例就可以了:< / p>
class Test a where
elm :: a
instance (Test a, Test b) => Test (a,b) where
elm = (elm, elm)
更有可能的是,您实际上还有其他方法可以使用x
,例如
class Test x a where
elm :: a
beech :: x -> a
在这种情况下,将elm
分解为更简单的超类可能是有意义的:
class PreTest a where
elm :: a
class (PreTest a) => Test x a where
beech :: x -> a
或者,您可以通过其他方式获取x
信息,而不是通过方法的签名。这可以通过fundep完成:
{-# LANGUAGE FunctionalDependencies #-}
class Test x a | a->x where
elm :: a
这表明任何类型Test _ a
只能有一个a
实例,因此编译器可以明确地从中推断出x
。
但是我非常怀疑你并不是真的想要这样 - 这样的类比完整的双参数类灵活得多。现代Haskell倾向于支持与fundep MultiParamTypeClasses相当的大致相同的关联类型同义词,并且当x
和a
实际上是两个独立参数时,大多使用MTPC。