Haskell中的演绎类型失败。

时间:2016-03-22 00:39:56

标签: haskell

class (Eq a) => My a where
    f:: (a,a) -> (a,a)

instance My Int where
    f (a,b) = (a,b)

instance My Char where
    f (a,b) = (a,b)

"对#34;的专业化。它使编译错误,我不知道为什么。请帮助修复它并解释为什么它是错误的。

instance (My a, My b) => My (a,b) where
    f ((a,b), (c,d)) = ( (f (a,b)), (f (c,d)) )

错误:

test.hs:11:31:
    Could not deduce (a ~ b)
    from the context (Eq (a, b), My a, My b)
      bound by the instance declaration at test.hs:10:10-33
      `a' is a rigid type variable bound by
          the instance declaration at test.hs:10:10
      `b' is a rigid type variable bound by
          the instance declaration at test.hs:10:10
    Expected type: (a, b)
      Actual type: (a, a)
    In the return type of a call of `f'
    In the expression: (f (a, b))
    In the expression: ((f (a, b)), (f (c, d)))
Failed, modules loaded: none.

2 个答案:

答案 0 :(得分:3)

错误消息是正确的。在你的元组实例中,你有

   f :: ((a,b), (a,b)) -> ((a,b), (a,b))

其中ab通常是不同的类型。但是对于任何实例,f只能在(a,a)元组上运行,即您需要类型相等a ~ b。因此

instance (My a) => My (a,a) where
  f (ab, cd) = (f ab, f cd)

会工作......或者,实际上,我记得这会导致一些问题(忘记了什么),你应该更好地使等式约束显式

instance (My a, a~b) => My (a,b) where

答案 1 :(得分:3)

您可能需要以下实例:

false

高于instance (My a, My b) => My (a,b) where f ((a, b), (c, d)) = case (f (a, c), f (b, d)) of ((a1, a2), (b1, b2)) -> ((a1, b1), (a2, b2)) (a, c) :: (a, a),因此我们将(b, d) :: (b, b)应用于f。我们返回一对((a, a), (b, b))类型,我们对其进行重新排序,以获得((a, b), (a, b))