Haskell: não pode usar “mapa putStrLn”?
Pergunta
Eu tenho uma lista de strings, e tentei isso:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
Isso não funcionou, e eu não consigo entender o porquê.
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'
Alguma dica? Acho que tem a ver com o mapa de retornar uma lista e não um valor, mas eu não encontrar uma maneira fácil de corrigir isso.
Neste momento, a única forma que conheço para imprimir uma lista de strings é escrever uma função que irá iterar a lista, imprimindo cada elemento (impressão se a lista for [a], mas imprimir e recurse se é (a: b )). Mas seria muito simples de mapa de uso apenas ...
Obrigado!
Solução
O tipo de função main
deve ser IO t
(onde t
é um tipo variável). O tipo de map putStrLn ls
é [IO ()]
. Isso porque você está recebendo esta mensagem de erro. Você pode verificar isso mesmo, executando o seguinte em ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
Uma solução para o problema está usando mapM
, que é a versão "monádico" de map
. Ou você pode usar mapM_
que é o mesmo que mapM
mas não recolhe os valores devolvidos a partir da função. Desde que você não se preocupam com o valor de retorno de putStrLn
, é mais apropriado usar mapM_
aqui. mapM_
tem o seguinte tipo:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Aqui está como usá-lo:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Outras dicas
A resposta de Ayman faz mais sentido para esta situação. Em geral, se você tem [m ()]
e você quer m ()
, em seguida, usar sequence_
, onde m
pode ser qualquer mônada incluindo IO
.