Haskell: nicht „Karte putStrLn“ nutzen?
Frage
Ich habe eine Liste von Strings, und versuchte, dies:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
Das hat nicht funktioniert, und ich kann nicht verstehen, warum.
ghc print-list.hs
print-list.hs:3:0:
Couldn't match expected type `IO t' against inferred type `[IO ()]'
In the expression: main
When checking the type of the function `main'
Für Hinweise? Ich nehme an, es hat mit der Karte zu tun, um eine Liste und keinen Wert zurückgegeben wird, aber ich habe nicht einen einfachen Weg finden, dies zu beheben.
Im Moment der einzige Weg, ich kenne eine Liste von Zeichenkette drucken ist, eine Funktion zu schreiben, die die Liste iterieren, jedes Element Druck (Druck, wenn die Liste ist [a], aber Druck und Rekursion, wenn es (a: b )). Aber es wäre viel einfacher gerade Karte verwenden ...
Danke!
Lösung
Der Typ der main
Funktion sollte sein IO t
(wo t
eine Variable vom Typ ist). Die Art der map putStrLn ls
ist [IO ()]
. Der Grund, warum Sie erhalten diese Fehlermeldung. Sie können dies selbst überprüfen, indem Sie den folgenden in ghci
ausgeführt wird:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
Eine Lösung für das Problem wird mit mapM
, die die „monadischen“ -Version von map
ist. Oder Sie verwenden können, mapM_
das ist die gleiche wie mapM
sammelt allerdings nicht die zurückgegebenen Werte aus der Funktion. Da Sie nicht über den Rückgabewert von putStrLn
egal, es ist besser geeignet mapM_
hier zu verwenden. mapM_
hat den folgenden Typ:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Hier ist, wie es zu benutzen:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Andere Tipps
Ayman Antwort macht am meisten Sinn für diese Situation. wenn Sie in der Regel [m ()]
und Sie wollen m ()
, dann sequence_
verwenden, wo m
jede Monade einschließlich IO
sein kann.