2014-05-07 5 views
0

les gars pouvez-vous m'aider à corriger ce code?Haskell programe correctif

import Data.Char 
import Data.List 

-- 1 2 3 4 5 6 7 8 

colors = [1,2,3,4,5] 

--game :: [Integer] -> [Char] 
game a = do 
     let black = test a color 
      white = (test2 a color) - black 
     let x = [a] ++ createScore black white 
     show x 

test [] [] = 0 
test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys 

test2 a b = length (intersection a b) 

intersection first second = [n | n <- first , isInfixOf [n] second] 

createScore c b = [(take c (repeat 1) ++ take b (repeat 0))] 

start = do 
     a <- getLine 
     let b = map read $ words a 
     --print b 
     game b 
     start 

J'ai un problème avec les fonctions IO et nonIO. description du programme:

  1. lire les données de la ligne
  2. convertir les données à la liste des int
  3. jeu de fonction d'appel (qui prend Liste des int comme Parametr)
  4. faire quelques calculs
  5. imprimer
  6. classement Recommencez à partir de 1

Le problème est en début de fonction et je n'ai aucune idée de comment le réparer.

Merci pour votre aide.

+0

Vous devez ajouter le message d'erreur. – Nicolas

Répondre

3

Il y a quelques petites choses qui ne fonctionnent pas vraiment avec le code que vous nous avez donné.

Je vais travailler à travers les erreurs de compilation.

Lors de la première charge, nous obtenons une erreur de nom:

ex1.hs:10:26: 
Not in scope: 'color' 
Perhaps you meant 'colors' (line 6) 

(et encore à la ligne 11)

Bien sûr, le compilateur est correct et nous avons juste besoin de changer les noms appropriés pour correspondre.

Nous récupérons l'intéressant, je suppose que vous faites référence en ce qui concerne IO et les fonctions non-IO:

ex1.hs:28:7: 
Couldn't match type '[]' with 'IO' 
Expected type: IO Char 
    Actual type: String 
In the return type of a call of 'game' 
In a stmt of a 'do' block: game b 
In the expression: 
    do { a <- getLine; 
     let b = map read $ words a; 
     game b; 
     start } 

L'erreur est votre utilisation de game b dans le bloc IO.

L'annotation de type que vous avez commentée sur la définition de fonction de game est en fait correcte - il s'agit de [Integer] -> [Char].

En tant que tel c'est une fonction pure et nous n'avons pas besoin d'utiliser la notation do pour le décrire comme nous le ferions avec quelque chose qui traite de IO - parce que vous avez utilisé la notation ici avec un argument d'une liste, le do expression représente un calcul dans le contexte d'une liste, pas un calcul d'E/S, donc l'appeler de start a une incompatibilité de type, il attend IO, mais il a trouvé [].

Nous pouvons commencer à le réparer en transformant game en une pure fonction, en utilisant une expression let-in.

game :: [Integer] -> [Char] 
game a = let black = test a colors 
      white = (test2 a colors) - black 
      x = [a] ++ createScore black white 
     in show x 

Maintenant, nous avons une fonction qui retourne la chaîne de l'entrée et son score.

Le compilateur donne maintenant l'erreur Expected type: IO Char, Actual type: [Char], car nous essayons toujours d'utiliser une expression non-IO dans le bloc principal do.

Nous pouvons régler en imprimant en fait la chaîne à stdout, à l'aide d'impression, de sorte que votre original

--print b 
game b 

peut juste être

print $ game b 

À ce stade, le programme compile!

Malheureusement, ce n'est pas tout à fait exact, lorsque nous exécutons cela et tapez une liste d'entiers comme 1 2 3, nous obtenons l'exception ex1.hs:(14, 1)-(15,66): Non-exhaustive patterns in function test.

Celui-ci se résume à votre définition de test comme:

test [] [] = 0 
test (x:xs) (y:ys) 

Ne tient pas compte de la possibilité d'une liste soit vide - parce que le chèque est toujours entre les éléments de tête des listes probablement la le plus petit changement pour corriger cela pourrait être:

test (x:xs) (y:ys) = if x == y then 1+test xs ys else 0+test xs ys 
test _ _ = 0 

Et maintenant le programme compile et exécute. J'espère que cela a du sens.

+0

merci pour cette réponse utile mais je reçois encore message d'erreur 'ERREUR - Impossible de trouver" show "fonction pour: *** Expression: commencer *** De type: IO a' – Alrick

+0

hey Alrick - d'abord, vous ressemble Utilisez des câlins, donc désolé de citer mes messages d'erreur ghci à vous. Cette erreur que vous obtenez est probablement parce que vous avez 'show start' quelque part dans votre code, les câlins ne peuvent pas 'montrer' cela parce que le type polymorphe' IO a' n'est pas un membre de la classe de type 'show'. Autrement dit, vous avez un type avec un paramètre inconnu 'a', alors comment les câlins peuvent-ils savoir quoi imprimer? Pour ce que ça vaut, voici le texte complet du code donné qui va compiler et fonctionner sur ma machine: https://gist.github.com/kjgorman/8e999820d45dfc2e2884 – kieran

+0

Merci cela fonctionne maintenant. Hugs a un problème avec la récursion infinie je l'ai fixé par if, else statement – Alrick

0

game est (ou devrait être) une fonction pure, vous devez donc l'appeler avec une fonction qui renvoie une valeur d'E/S dans votre fonction start, e. g. print $ game b. Il n'y a pas non plus de raison d'utiliser la notation do (vous pouvez le faire parce que [a] est aussi une monade, mais vous n'en profitez en aucune façon). Vous pouvez simplement utiliser game a = show x et remplacer les instructions let par un bloc where (ou utiliser let ... in). test devrait être capable de traiter le cas d'une liste étant vide et l'autre non, ou vous devez vous assurer que les deux listes sont toujours de la même taille.