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, doc'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 Stringet un Mapvous voulez fournir un String. Si je lis ceci, dans Haskell, j'en déduirai que vous voulez probablement utiliser le Mappour extraire quelque chose d'utile pour construire un fichier String. En effet, la seule sortie de votre fonction est un String. Puisque le Mapn'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' Mapinté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 domot. 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 domot 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 newMapqui est modifiée comme vous le souhaitez. Et vous fournissez le String ""comme sortie. Cependant, le newMapne 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

Posts les plus consultés de ce blog

Erreur Symfony : "Une exception a été levée lors du rendu d'un modèle"

Détecter les appuis sur les touches fléchées en JavaScript

Une chaîne vide donne "Des erreurs ont été détectées dans les arguments de la ligne de commande, veuillez vous assurer que tous les arguments sont correctement définis"