11
votes

Impossible de faire correspondre le type attendu `int 'avec le type réel` Integer'

J'ai le code HASKELL suivant: xxx

qui donne l'erreur suivante: xxx

Je soupçonne que dans le triple (0, 0, 0,0) Les 0 sont TYPE INT . Est 0 Toujours Type int ou est GHCI déduire le type comme int dans ce cas? Si le plus tard, comment cela est-il forcer à être taper entier à la place? Ou y a-t-il quelque chose d'autre qui provoque cette erreur?



3
votes

On en est déduit, vous pouvez donc simplement modifier la signature de type de maxratio . Néanmoins, si vous avez besoin de changer un int sur un entier , utilisez tointère :: (intégral A) => A -> entier


3 commentaires

J'utilise habituellement detintegeral , surtout lorsque j'utilise longueur . Y a-t-il une différence entre l'utilisation d'utiliser detintegal plutôt que totinteger ?


@ Code-gourou: Je pense que la seule différence est que detintegal peut renvoyer n'importe quel type num , il est donc un peu moins clair lorsque vous le lisez quel type il va être déduit .


@ Code-Guru: En réalité, detintegal est défini comme detintegal = detinteger. totinteger - il est donc certainement juste un compromis entre la flexibilité et la lisibilité



18
votes

Haskell peut généralement déduire le type de littéraux numériques tels que 0 comme quel que soit le type approprié dont vous avez besoin. C'est parce que cela sait quelles fonctions vous les transmettez; Si j'ai une fonction phi :: entier -> integer , et j'appelle phi 0 , Haskell sait que ce particulier 0 doit avoir été un entier . C'est aussi bien si j'appelle une fonction pho :: int -> int avec pho 0 ; que particulier 0 est déduit d'être un int .

Cependant int et entier sont des types différents, et il n'y a aucun moyen d'un 0 peut être transmis aux deux phi et pho .

Votre problème est simplement que les tuples que maxratio sont saisis sont saisis (par vous) (int, int, double) , mais celui-ci est construit comme (n, phi n, ratio) . Etant donné que Phi prend et renvoie integer , le n dans cette expression doit être un entier . Mais alors cela ne fonctionne pas pour maxratio , vous obtenez donc l'erreur.

Selon le type que vous souhaitez réellement ( int ou integer ), tout ce que vous avez à faire est de modifier la signature de type de Phi ou maxratio de sorte qu'ils travaillent avec le même type de nombre. Haskell décidera que votre 0 s littéralement écrit est le type numérique nécessaire pour faire ce travail, fourni il y en a un que peut le faire fonctionner !

Notez que l'erreur envoyée spécifiquement vous a dit qu'il était n dans (n, phi n, ratio) qui devrait être censé être un int et était en réalité un entier . Le (0, 0, 0,0) tuple n'est jamais mentionné. Souvent, les erreurs de type proviennent d'une part autre que lorsque le compilateur vous indique (puisque tout le compilateur peut faire est de repérer que différentes chaînes d'inférence produisent des exigences incohérentes sur le type de quelque chose, sans aucun moyen de savoir quelle partie de l'ensemble du processus est "faux" ), mais dans ce cas, il a assez bien fait.

Haskell obtient un mauvais représentant (assez justifié) pour des messages d'erreur impénécrutables, mais cela peut aider beaucoup à partir de ce que le compilateur vous dit est le problème et essayer de déterminer pourquoi les faits Il se plaint de provoquer votre code. Ce sera douloureux au début, mais vous développerez rapidement une alphabétisation de base dans les messages d'erreur de Haskell (au moins les plus simples) qui vous aideront à repérer ce type d'erreurs vraiment rapidement, ce qui rend le compilateur une très puissante détection d'erreur. système pour vous.


1 commentaires

Merci pour l'explication claire. Je pensais que 0 était polymorphe dans son type, mais mes yeux noob ne pouvaient voir aucune autre raison de l'inférence de type qui a donné l'erreur. Bien sûr, j'ai simplement manqué ma déclaration de type explicite pour maxratio .



1
votes

Vos signatures de type sont incohérentes - remplacez int avec entier tout au long de.


0 commentaires