2010-11-14 16 views
4

J'ai besoin d'aide avec les types en Haskell ...Aide avec Haskell IO tapant

Voici le code que je travaille sur:

loadManyPeople :: [FilePath] → IO [Person] 
loadManyPeople fs = do 
    return $ concat $ map loadPeople fs 

loadPeople :: FilePath → IO [Person] 
loadPeople file = do 
    lines ← getLines file 
    return $ map parsePerson lines 

loadPeople est très bien. Je veux que loadManyPeople charge toutes les personnes de chaque fichier, puis les concatène dans une liste de personnes. Je ne connais pas encore Haskell et j'ai besoin d'aide pour faire en sorte que les types s'entraînent.

Merci pour l'aide. Alex

Répondre

12

loadPeople vous donne un IO [Person], donc map loadPeople vous donne un [IO [Person]] cependant d'utiliser concat, vous auriez besoin d'un [[Person]].

Pour résoudre ce problème, vous pouvez utiliser la séquence, qui est une fonction de type [IO a] -> IO [a], de sorte que vous pouvez faire ce qui suit:

loadManyPeople fs = do 
    manyPeople <- sequence $ map loadPeople fs 
    return $ concat manyPeople 

Cependant, il y a un raccourci pour l'utilisation map puis sequence: mapM qui a le type (a -> IO b) -> [a] -> IO [b]. Avec mapM votre code ressemble à ceci:

loadManyPeople fs = do 
    manyPeople <- mapM loadPeople fs 
    return $ concat manyPeople 

Cela peut être écrit de manière plus succincte en utilisant Applicative:

import Control.Applicative 
loadManyPeople fs = concat <$> mapM loadPeople fs 
+5

Et il est à noter que '<$>' est juste 'fmap', que vous pouvez ou ne peut pas J'ai déjà vu. –

+0

merci les gars. Des trucs géniaux –