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

时间:2016-09-15 20:38:09

标签: haskell ghc typeclass

这是几分钟前刚刚提出的问题的修改 - 但是对于这种情况我遇到了问题......

我有以下问题:我定义了一个类型类,并希望将此类的类型元组声明为实例。但我不知道如何让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会导致麻烦...... 怎么做到这一点?提前感谢任何建议!

1 个答案:

答案 0 :(得分:3)

这与元组没有任何关系。问题只是x出现在班主任中,而不是elm的签名 - 所以当x时无法确定要用作elm类型的内容在代码中的某处出现。

的确,如果elmTest的唯一方法,则根本不需要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相当的大致相同的关联类型同义词,并且当xa实际上是两个独立参数时,大多使用MTPC。