Question

Je suis nouveau à Haskell et face à une erreur « ne peut pas construire de type infini » que je ne peux pas donner un sens.

En fait, au-delà de cela, je ne l'ai pas été en mesure de trouver une bonne explication de ce que signifie cette erreur même, donc si vous pouvez aller au-delà de ma question fondamentale et d'expliquer l'erreur « type infini », je l'apprécie vraiment .

Voici le code:

intersperse :: a -> [[a]] -> [a]

-- intersperse '*' ["foo","bar","baz","quux"] 
--  should produce the following:
--  "foo*bar*baz*quux"

-- intersperse -99 [ [1,2,3],[4,5,6],[7,8,9]]
--  should produce the following:
--  [1,2,3,-99,4,5,6,-99,7,8,9]

intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:y:xs) = x:s:y:intersperse s xs

Et voici l'erreur en essayant de le charger dans l'interpréteur:

Prelude> :load ./chapter.3.ending.real.world.haskell.exercises.hs
[1 of 1] Compiling Main (chapter.3.ending.real.world.haskell.exercises.hs, interpreted )

chapter.3.ending.real.world.haskell.exercises.hs:147:0:
Occurs check: cannot construct the infinite type: a = [a]
When generalising the type(s) for `intersperse'
Failed, modules loaded: none.

Merci.

-

Voici quelques corrigé le code et une ligne directrice générale pour faire face à l'erreur « de type infini » dans Haskell:

code corrigé

intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) =  x ++ s:intersperse s xs 

Quel était le problème:

Ma signature de type indique que le second paramètre à entremêler est Liste des listes . Par conséquent, quand je modèle en correspondance avec "s (x: y: xs)", x et y sont devenus Listes . Et pourtant, je traitais x et y comme éléments, non pas des listes.

Lignes directrices pour traiter l'erreur "de type infini":

La plupart du temps, quand vous obtenez cette erreur, vous avez oublié les types des différentes variables que vous traitez, et vous avez tenté d'utiliser une variable comme si elle était un autre type que ce qu'il est. Regardez attentivement quel type tout est contre la façon dont vous l'utilisez, et cela découvrir généralement le problème.

Était-ce utile?

La solution

Le problème est dans la dernière clause, où vous traitez x et y comme éléments, alors qu'ils sont des listes. Cela fonctionne:

intersperse _ [] = []
intersperse _ [x] = x 
intersperse s (x:y:xs) = x ++ [s] ++ y ++ intersperse s xs

L'erreur de type infinie se produit car le: l'opérateur est de type a -> [a] -> [a], pendant que vous le traiter comme [a] -> a -> [a], ce qui signifie que [a] doit être identifié par un, ce qui voudrait dire qu'une est une liste infiniment imbriqués. Ce n'est pas permis (et non ce que vous voulez dire, de toute façon).

Modifier il y a aussi un autre bogue dans le code ci-dessus. Il devrait être:

intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) = x ++ [s] ++ intersperse s xs

Autres conseils

Souvent, l'ajout d'une définition de type explicite peut rendre le message d'erreur de type du compilateur plus logique. Mais dans ce cas, la saisie explicite rend le message d'erreur du compilateur pire.

Regardez ce qui se passe quand je laisse GHC deviner le type de intersperse:

Occurs check: cannot construct the infinite type: a = [a]
  Expected type: [a] -> [[a]] -> [[a]]
  Inferred type: [a] -> [[a]] -> [a]
In the second argument of `(:)', namely `intersperse s xs'
In the second argument of `(:)', namely `y : intersperse s xs'

clairement vers les points que le bogue dans le code. En utilisant cette technique, vous ne devez pas regarder tout et réfléchir sur les types, comme d'autres ont suggéré de faire.

Je peux me tromper, mais il semble que vous essayez de résoudre un problème plus difficile. Votre version de intersperse ne se contente pas intercaler la valeur avec le tableau, mais aussi aplatit un niveau.

Le module List en Haskell fournit en fait une fonction intersperse. Il met à la valeur donnée entre chaque élément dans la liste. Par exemple:

intersperse 11 [1, 3, 5, 7, 9] = [1, 11, 3, 11, 5, 11, 7, 11, 9]
intersperse "*" ["foo","bar","baz","quux"] = ["foo", "*", "bar", "*", "baz", "*", "quux"]

Je suppose que c'est ce que vous voulez faire parce que c'est ce que mon professeur voulait faire quand j'apprenais Haskell. Je pourrais, bien sûr, être totalement.

J'ai aussi trouvé cette qui explique la sens de l'erreur.

Chaque fois que l'interpréteur / compilateur me donne cette erreur, il est parce que je suis en utilisant une tuple de type comme paramètre formel paramétré. Tout fonctionne correctement Supprimer la définition du type de la fonction, qui contenait des variables de type.

Je ne peux toujours pas comprendre comment les deux fixer et maintenir la définition du type de fonction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top