Haskell: non può usare “mappa putStrLn”?
Domanda
Ho una lista di stringhe, e provato questo:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
che non ha funzionato, e non riesco a capire perché.
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'
Eventuali suggerimenti? Suppongo che ha a che fare con il programma di restituzione di un elenco e non un valore, ma non ho trovato un modo semplice per risolvere il problema.
In questo momento l'unico modo che conosco per stampare una lista di stringhe è quello di scrivere una funzione che iterare la lista, la stampa di ogni elemento (stampare se la lista è [a], ma la stampa e ricorsivamente se si tratta di (a: b )). Ma sarebbe molto più semplice di utilizzare solo carta ...
Grazie!
Soluzione
Il tipo della funzione main
dovrebbe essere IO t
(dove t
è una variabile di tipo). Il tipo di map putStrLn ls
è [IO ()]
. Questo il motivo per cui si stanno ottenendo questo messaggio di errore. È possibile verificare questo da soli con il seguente in ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
Una soluzione al problema sta usando mapM
, che è la versione "monade" di map
. Oppure è possibile utilizzare mapM_
che è lo stesso come mapM
ma non raccoglie i valori restituiti dalla funzione. Dal momento che non si preoccupano il valore di ritorno di putStrLn
, è più opportuno utilizzare mapM_
qui. mapM_
ha il seguente tipo:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Ecco come usarlo:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Altri suggerimenti
La risposta di Ayman rende più senso per questa situazione. In generale, se avete [m ()]
e vuoi m ()
, quindi utilizzare sequence_
, dove m
può essere qualsiasi monade tra cui IO
.