2009-05-31 37 views
50

que tienen una lista de cadenas, y probamos este:Haskell: no se puede usar "map putStrLn"?

ls = [ "banana", "mango", "orange" ] 

main = do 
     map PutStrLn list_of_strings 

eso 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 sugerencia? Supongo que tiene que ver con que el mapa devuelva una lista y no un valor, pero no encontré una manera fácil de arreglar esto.

En este momento, la única manera que conozco de imprimir una lista de cadenas es escribir una función que iterará la lista, imprimiendo cada elemento (imprimir si la lista es [a], pero imprimir y recursar si es (a: segundo)). Pero sería mucho más fácil de usar el mapa ...

¡Gracias!

Respuesta

89

El tipo de la función main debe ser IO t (donde t es una variable de tipo). El tipo de map putStrLn ls es [IO()]. Este es el motivo por el que recibes 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 al problema está utilizando mapM, que es la versión "monádico" de map. O puede usar mapM_ que es lo mismo que mapM pero no recoge los valores devueltos de la función. Como no le importa el valor de retorno de putStrLn, es más apropiado usar 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 
+15

Algo que ojalá hubiera aprendido mucho antes es que hay otro mapM definido en Data.Traversable. Este mapM trabaja más estructuras de datos además de listas, como mapas y matrices. –

+5

Siempre pensé que 'main' debería ser de tipo' IO() ', nunca supe que podría ser' forall t. IO t'. Eso muestra cómo puedes aprender algo nuevo cada día :-) –

19

respuesta de Ayman tiene más sentido para esta situación. En general, si tiene [m()] y quiere m(), entonces use sequence_, donde m puede ser cualquier mónada incluyendo IO.

Cuestiones relacionadas