2010-11-16 26 views
1

Je suis nouveau à Haskell et j'essaie de comprendre comment fonctionne IO. J'ai une structure de données, un arbre, que je veux sérialiser dans un fichier et ensuite désérialiser vers la structure de données. Il semble que je devrais être capable de le faire à travers le spectacle et la lecture, mais mon utilisation de la lecture est une erreur. Voici la partie pertinente de mon code:Sérialisation de structures de données dans un fichier avec Haskell?

data Tree = Answer String | Question String Tree Tree deriving (Read, Show) 

fileToTree :: (Read a) => FilePath -> IO a 
fileToTree filePath = do 
    dataStruct <- readFile filePath 
    return (read dataStruct) 

treeToFile :: (Show a) => a -> FilePath -> IO() 
treeToFile dataStruct filePath = do 
    writeFile filePath (show dataStruct) 

main = do 
    let filePath = "data.txt" 
    let ds = fileToTree filePath 
    ask ds 
    treeToFile ds filePath 

ask :: Tree -> IO() 
ask (Question q yes no) = do 
    putStrLn q 
    answer <- getLine 

L'erreur que je reçois est « Impossible de ne pas correspondre type attendu « Arbre » contre type inféré « IO a » dans le premier argument de« demander ». Il semble que la lecture devrait renvoyer un type d'arbre, mais il retourne un type d'E/S. Existe-t-il un moyen de le contraindre à un type d'arbre, ou suis-je totalement mal lire le problème?

Répondre

2

Notez que fileToTree renvoie une valeur dans IO. Cela signifie que la ligne let ds = fileToTree filePath lie IO a à l'identificateur ds. Si vous voulez travailler sur la valeur que vous obtenez dans la monade IO, vous devez utiliser la fonction >>= (bind) de la monade IO en remplaçant la ligne let ds = fileToTree filePath par ds <- fileToTree filePath. Cela liera quelque chose de type a à ds, dans un sens dépouillant le IO externe. L'appel au ask va enfin unifier a avec Tree.

Avec cela, il semble y avoir un problème avec ask. Ce que vous avez ci-dessus ne compile pas, et il semble que vous n'utilisez pas answer, donc je devine que c'était une erreur dans le collage de votre code.

+0

Merci beaucoup! J'ai essayé de déplier l'IO dans la fonction fileToTree en faisant quelque chose comme 'return (read dataStruct :: Tree)', qui causait des erreurs parce que fileToTree ne retournait pas un 'IO a'. Développer dans la main est quelque chose que je n'ai jamais pensé. – stomcavage