Wiederholung von IO-Aktionen in Haskell
Frage
Ich versuche, ein kleines Programm neu zu schreiben, das Informationen von einer oder mehreren Webseiten extrahiert und sie dann in Flash-Karten umwandelt.Kleiner Ausschnitt hier:
-- | this takes a string and produces IO [Tag String]
getVerbePage x = fmap parseTags $ openURL $ "http://leconjugueur.lefigaro.fr/conjugaison/verbe/" ++ x ++ ".html"
main = do
tags <- getVerbePage "aller"
-- | from here I do whatever I like with a clean [Tag String]
Ich habe kein Problem damit, einen nach dem anderen zu machen, die E/A geht in die Do-Schleife und dann mache ich, was ich brauche, mit reinen Funktionen.Ich verstehe nicht wirklich, wie man das auf wiederkehrende Weise macht. Im Grunde geht es mir um Folgendes:
-- | this takes a string and produces IO [Tag String]
getVerbePage x = fmap parseTags $ openURL $ "http://leconjugueur.lefigaro.fr/conjugaison/verbe/" ++ x ++ ".html"
main = do
verbsString <- getLine -- | example input "aller pouvoir"
let verbs = splitOn " " verbsString -- | list of strings
pages <- getVerbePages verbs
-- | from here use pure functions on pages, which would be type [[Tag String]]
getVerbePages :: [String] -> [[Tag String]] -- | I guess.
getVerbePages ps = ??????
Die Frage ist, wie schreibe ich getVerbePages, um jede Zeichenfolge in ps zu durchlaufen und sie sauber zurückzugeben?Bis zu diesem Zeitpunkt kam ich gut mit rekursiven Aktionen und all dem zurecht, da ich eigentlich ein Haskell-Neuling bin, aber ich verstehe nicht, wie das alles funktioniert, wenn eine E/A-Aktion wiederholt wird.
Lösung
Wenn Sie dasselbe wiederholen möchten IO
Aktion über eine Liste von Dingen, dann können Sie verwenden mapM
.Seine Typsignatur ist (hier spezialisiert auf IO
)
mapM :: (a -> IO b) -> [a] -> IO [b]
Verwenden Sie es mit Ihrem getVerbPage
würde bedeuten, dass die a
Typvariable ist String
und das b
Typvariable ist [Tag String]
.Dann hättest du es getan mapM getVerbPage :: [String] -> IO [[Tag String]]
, was Sie als Definition von wünschen getVerbPages
.