2016-03-22 4 views
3
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) 

「ペアの特殊化」。それはコンパイルエラーを引き起こし、私は理由を知らない。それを修復し、それがなぜ誤りであるか私に説明してください。ハスケルでは減算タイプが失敗します。

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. 

答えて

3

エラーメッセージは上のスポットです。あなたのタプルのインスタンスでは、abが一般異なったタイプである

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

を持っています。しかし、いずれの場合でも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 
+2

問題は、GHCが平等を持っていない限り、あなたが与えた最初のインスタンスにコミットしないということです。私はそれがタイプエラーにつながるのを見たことが分かっていますが、詳細を覚えていません。 – dfeuer

3

行う必要があります覚えています:

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))を取得します。

関連する問題