2012-01-13 7 views
1

J'ai ceci:IO String et IO Type de données

data SomeData = SomeData Int Int 

getDataFromUser :: SomeData 
getDataFromUser = do 
{ 
    read (getLine)::SomeData; 
} 

Cette compilation ne marche pas: Type attendu chaîne type réel IO Chaîne

Comment puis-je résoudre ce problème? J'ai besoin de cette désérialisation de données ...

+0

Les réponses ci-dessous sont " plus utile "dans le sens où ils répondent au problème conceptuel que vous avez; Cependant, vous pouvez également être intéressé par le correctif "moins utile", 'getDataFromUser :: IO SomeData; getDataFromUser = readLn'. –

Répondre

9

Vous essayez de traiter getLine comme une chaîne, mais c'est un IO String - une action d'E/S qui, lorsqu'elle est exécutée, produit une chaîne. Vous pouvez l'exécuter et obtenir la valeur résultant de l'intérieur d'un bloc do en utilisant <-, mais depuis getDataFromUser-t IO, son type doit être IO SomeData:

getDataFromUser :: IO SomeData 
getDataFromUser = do 
    line <- getLine 
    return $ read line 

De façon plus générale, je recommande la lecture d'un tutoriel sur IO Haskell, comme Learn You a Haskell's chapter on IO; c'est très différent des installations d'E/S de la plupart des autres langues, et cela peut prendre un certain temps pour s'habituer à la façon dont les choses s'articulent; il est difficile de transmettre une compréhension complète avec des réponses à des questions spécifiques comme celle-ci :)

7

Vous devez lire plus sur comment fonctionne Haskell IO et vous assurer de le comprendre.

Quelques points sur votre exemple. Si vous souhaitez utiliser read pour désérialiser à SomeData, vous devez fournir une instance Read pour le type. Vous pouvez utiliser la valeur par défaut un:

data SomeData = SomeData Int Int deriving (Read) 

Deuxièmement: getLine est une action IO qui retourne une String, pas un String; puisque read veut un String, c'est la cause de votre erreur. Ceci est plus proche de ce que vous voulez:

getDataFromUser :: IO SomeData 
getDataFromUser = do str <- getLine 
        return (read str) 

Cela peut être simplifié à ce qui suit, mais assurez-vous de comprendre l'exemple ci-dessus avant vous vous inquiétez trop à ce sujet:

getDataFromUser :: IO SomeData 
getDataFromUser = liftM read getLine