Der erwartete Typ 'Int' konnte nicht mit dem tatsächlichen Typ 'Integer' verglichen werden.

8

Ich habe den folgenden Haskell-Code:

%Vor%

was den folgenden Fehler ergibt:

%Vor%

Ich vermute, dass in der dreifachen (0, 0, 0.0) die 0% Int sind. Ist 0 immer Int oder gibt ghci in diesem Fall den Typ als Int ab? Wenn das später, wie zwinge ich es stattdessen, um% Integer zu sein? Oder gibt es noch etwas, das diesen Fehler verursacht?

    
Code-Apprentice 05.09.2012, 02:00
quelle

4 Antworten

15

Haskell kann im Allgemeinen den Typ numerischer Literale wie 0 als den geeigneten Typ ableiten, den Sie benötigen. Das liegt daran, dass es weiß, an welche Funktionen Sie diese weitergeben. Wenn ich eine Funktion phi :: Integer -> Integer habe und ich phi 0 anrufe, weiß Haskell, dass diese bestimmte 0 eine Integer sein muss. Es ist auch in Ordnung, wenn ich eine Funktion pho :: Int -> Int mit pho 0 ; das particular 0 wird als Int abgeleitet.

Allerdings sind Int und Integer verschiedene Typen und es gibt keine Möglichkeit, dass ein bestimmtes 0 an beide phi und pho übergeben werden kann.

Ihr Problem besteht einfach darin, dass die Tupel, mit denen maxRatio befasst ist, von Ihnen eingegeben werden ( (Int, Int, Double) ), aber dass ein solches Tupel als (n, phi n, ratio) konstruiert ist. Da phi Integer übernimmt und zurückgibt, muss n in diesem Ausdruck ein Integer sein. Aber das funktioniert nicht für maxRatio , daher erhalten Sie den Fehler.

Je nachdem, welchen Typ Sie wirklich wollten ( Int oder Integer ), müssen Sie nur die Typensignatur von phi oder maxRatio ändern, damit sie mit derselben Art von Zahl arbeiten . Haskell wird entscheiden, dass Ihr wörtlich geschriebener 0 s der numerische Typ ist, der notwendig ist, um diese Arbeit zu erledigen, vorausgesetzt gibt es einen , der funktioniert!

Beachten Sie, dass die Fehlernachricht speziell Ihnen mitgeteilt hat, dass es n in (n, phi n, ratio) war, von dem erwartet wurde, dass es ein Int war und tatsächlich ein Integer war. Das (0, 0, 0.0) -Tupel wird nie erwähnt. Oftmals kommen Typfehler von einem anderen Ort als dem, wo der Compiler Sie hinweist (da der Compiler nur feststellen kann, dass verschiedene Inferenzketten inkonsistente Anforderungen an den Typ von etwas ergeben, ohne zu wissen, welcher Teil des gesamten Prozesses "falsch" ist) ), aber in diesem Fall hat es ziemlich gut funktioniert.

Haskell erhält einen (ziemlich begründeten) schlechten Ruf für unergründliche Fehlermeldungen, aber es kann sehr hilfreich sein, mit dem zu beginnen, was der Compiler Ihnen sagt, ist das Problem und versuchen herauszufinden, warum die Fakten es beschweren sich über Ihren Code. Dies wird zunächst schmerzhaft sein, aber Sie werden schnell eine grundlegende Lese- und Schreibfähigkeit in Haskells Fehlermeldungen entwickeln (zumindest die einfacheren), die Ihnen helfen werden, diese Art von Fehlern wirklich schnell zu erkennen, was den Compiler zu einer sehr mächtigen Fehlererkennung macht System für Sie.

    
Ben 05.09.2012, 02:32
quelle
4

n wird aufgrund des Typs Int als maxRatio abgeleitet, während der Typ von phi angibt, dass es Integer sein sollte. Die einfachste Lösung ist, den Typ von maxRatio so zu ändern, dass Integer oder sogar nur a verwendet wird, da diese Werte nicht berührt werden.

    
hammar 05.09.2012 02:10
quelle
3

Es wird gefolgert, dass Sie einfach die Typensignatur von maxRatio ändern können. Wenn Sie jedoch eine explizite Int in eine Integer ändern müssen, verwenden Sie toInteger :: (Integral a) => a -> Integer

    
amindfv 05.09.2012 02:25
quelle
1

Ihre Typsignaturen sind inkonsistent - ersetzen Sie Int durch Integer durchgängig.

    
AndrewC 05.09.2012 15:02
quelle

Tags und Links