2016-03-22 9 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) 

Und "Spezialisierung für das Paar". Es macht Kompilierungsfehler und ich weiß nicht warum. Bitte helfen Sie es zu reparieren und erklären Sie mir, warum es ein Fehler ist.Abzugstypen scheitern in Haskell.

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

Fehler:

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. 

Antwort

3

Die Fehlermeldung ist vor Ort. In Ihrem Tupel Beispiel haben Sie

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

wo a und b im Allgemeinen unterschiedliche Typen sind. Aber für jeden Fall kann f nur mit (a,a) Tupeln arbeiten, d. H. Sie benötigen die Typgleichheit a ~ b. So

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

funktionieren würde ... oder, tatsächlich, ich erinnere mich dies einige Probleme verursacht (vergessen, was), und Sie sollten besser die Gleichheit Einschränkung explizit machen

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

Das Problem, denke ich, ist, dass GHC nicht zu der ersten Instanz verpflichtet wird, die Sie gegeben haben, es sei denn/bis es die Gleichheit in der Hand hat. Ich weiß, dass das zu Fehlern geführt hat, aber ich erinnere mich nicht an die Details. – dfeuer

3

Sie das folgende Beispiel wollen könnte stattdessen :

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)) 

Above (a, c) :: (a, a) und (b, d) :: (b, b), so wenden wir f denen. Wir bekommen ein Paar vom Typ ((a, a), (b, b)) zurück, das wir neu ordnen, um ((a, b), (a, b)) zu erhalten.