Map.insert provoquant une erreur dans Haskell sans raison
Voici la fonction que j'utilise:
threeWordFunction:: [String] -> Map.Map String [String] -> String
threeWordFunction [x, y, z] orbitingData = do
Map.insert z [x, y] orbitingData
""
Entraînant l'erreur suivante :
src\MyLib.hs:40:6: error:
* Couldn't match type `Map.Map String' with `[]'
Expected type: [[String]]
Actual type: Map.Map String [String]
* In a stmt of a 'do' block: Map.insert z [x, y] orbitingData
In the expression:
do Map.insert z [x, y] orbitingData
""
In an equation for `threeWordFunction':
threeWordFunction [x, y, z] orbitingData
= do Map.insert z [x,....] orbitingData
""
|
40 | Map.insert z [x, y] orbitingData
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
J'ai essayé tout un tas de correctifs mais je n'ai rien trouvé qui puisse causer cette erreur. La fonction essaie juste d'ajouter les chaînes à la carte, rien d'extraordinaire. Toute aide serait appréciée.
Solution du problème
Le problème
Comme le disent certains contributeurs, do
c'est là le problème. Cependant, laissez-moi essayer de décomposer ce que vous voulez (comme je peux le voir) et ce que vous faites.
threeWordFunction:: [String] -> Map.Map String [String] -> String
déclare le type de votre fonction. C'est ce que vous comptez faire. Avec une liste de String
et un Map
vous voulez fournir un String
. Si je lis ceci, dans Haskell, j'en déduirai que vous voulez probablement utiliser le Map
pour extraire quelque chose d'utile pour construire un fichier String
. En effet, la seule sortie de votre fonction est un String
. Puisque le Map
n'est pas une sortie, toute modification sera "perdue".
Quand j'ai lu ce que vous vouliez faire, vous avez affirmé vouloir insérer une valeur dans le fichier Map
. Donc, je suppose que vous voulez sortir votre fichier Map
. Et là je peux déduire ta première erreur: tu penses avec effet secondaire. Je suppose que vous vouliez modifier l' Map
intérieur de votre fonction et que vous vous attendiez à ce que la carte soit modifiée en dehors de la fonction. Mais ce n'est pas comme ça que Haskell fonctionne. C'est ainsi que fonctionnent la plupart des langages avec des fonctionnalités impératives.
Donc, pour ce faire, vous voulez utiliser un do
mot. L'état d'esprit derrière cela est de fournir une séquence d'instructions comme dans un bloc C avec des accolades. Et c'est faux. En Haskell, le do
mot est sucre syntaxique et pointe le fait que vous êtes dans une monade... Donc le résultat de votre calcul sera probablement une monade. Mais ce n'est pas ce que dit le type de fonction. Le compilateur produit donc une erreur.
Que pouvez-vous faire pour être cohérent avec votre type
Compte tenu du type, une solution sera celle fournie par Chi.
threeWordFunction [x, y, z] orbitingData = let newMap = Map.insert z [x, y] orbitingData in ""
Le compilateur ne se plaindra plus. Vous construisez une nouvelle carte newMap
qui est modifiée comme vous le souhaitez. Et vous fournissez le String
""
comme sortie. Cependant, le newMap
ne sera jamais joignable en dehors de votre fonction. L'insert ne sert donc à rien.
Que pouvez-vous faire pour répondre à votre besoin
Changer le type... Le type dans Haskell fournit une spécification qui définit clairement les solutions valides attendues (plus ou moins).
Vous pouvez donc vouloir quelque chose qui fournit explicitement une carte.
threeWordFunction:: [String] -> Map.Map String [String] -> Map.Map String [String]
ou une carte et une chaîne
threeWordFunction:: [String] -> Map.Map String [String] -> (Map.Map String [String], String)
Vous pouvez également utiliser la monade comme State mais cela peut être trop pour votre niveau.
Compte tenu du nouveau type, vous pouvez désormais renvoyer une entité correspondant à vos besoins.
threeWordFunction:: [String] -> Map.Map String [String] -> (Map.Map String [String], String)
threeWordFunction [x, y, z] orbitingData =
let newMap = Map.insert z [x, y] orbitingData
in (newMap, "")
NB si vous souhaitez toujours fournir a en ""
tant que chaîne, cela indique probablement que vous n'en avez pas besoin.
J'espère que cela vous aidera à comprendre le problème.
Commentaires
Enregistrer un commentaire