Haskell: no puede utilizar “mapa putStrLn”?
Pregunta
Tengo una lista de cadenas, y intentado esto:
ls = [ "banana", "mango", "orange" ]
main = do
map PutStrLn list_of_strings
que no funcionó, y no puedo entender por qué.
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'
¿Alguna pista? Supongo que tiene que ver con el mapa devolviendo una lista y no un valor, pero no he encontrado una manera fácil de solucionar este problema.
En este momento la única forma que conozco para imprimir una lista de cadenas es escribir una función que va a recorrer la lista, la impresión de cada elemento (imprimir si la lista es [a], pero la impresión y recursivo si es (a: b )). Pero sería más más simple de usar sólo mapa ...
Gracias!
Solución
El tipo de la función de main
debe IO t
(donde t
es una variable de tipo). El tipo de map putStrLn ls
es [IO ()]
. Es por esto que está recibiendo este mensaje de error. Puede comprobar esto por sí mismo mediante la ejecución del siguiente en ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
Una solución para el problema está utilizando mapM
, que es la versión "monádico" de map
. O puede utilizar mapM_
que es el mismo que mapM
pero no recoge los valores devueltos por la función. Ya que no se preocupan por el valor de retorno de putStrLn
, es más apropiado utilizar mapM_
aquí. mapM_
tiene el tipo siguiente:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Aquí es cómo usarlo:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Otros consejos
La respuesta de Ayman tiene más sentido para esta situación. En general, si ha [m ()]
y desea m ()
, a continuación, utilizar sequence_
, donde m
puede ser cualquier mónada incluyendo IO
.