Haskell: can't use "map putStrLn"?
Solution 1
The type of the main
function should be IO t
(where t
is a type variable). The type of map putStrLn ls
is [IO ()]
. This why you are getting this error message. You can verify this yourself by running the following in ghci
:
Prelude> :type map putStrLn ls
map putStrLn ls :: [IO ()]
One solution to the problem is using mapM
, which is the "monadic" version of map
. Or you can use mapM_
which is the same as mapM
but does not collect the returned values from the function. Since you don't care about the return value of putStrLn
, it's more appropriate to use mapM_
here. mapM_
has the following type:
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
Here is how to use it:
ls = [ "banana", "mango", "orange" ]
main = mapM_ putStrLn ls
Solution 2
Ayman's answer makes most sense for this situation. In general, if you have [m ()]
and you want m ()
, then use sequence_
, where m
can be any monad including IO
.
Jay
Updated on April 18, 2020Comments
-
Jay about 4 years
I have a list of strings, and tried this:
ls = [ "banana", "mango", "orange" ] main = do map PutStrLn list_of_strings
That didn't work, and I can't understand why.
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'
Any hints? I suppose it has to do with map returning a list and not a value, but I didn't find an easy way to fix this.
Right now the only way I know to print a list of strings is to write a function that will iterate the list, printing each element (print if the list is [a], but print and recurse if it's (a:b)). But it would be much simpler to just use map...
Thanks!
-
Dietrich Epp almost 15 yearsSomething that I wish I'd learned a lot sooner was that there's another mapM defined in Data.Traversable. This mapM works more data structures in addition to lists, such as maps and arrays.
-
Dave almost 15 yearsI always thought that
main
should be of typeIO ()
, never knew it could beforall t. IO t
. That shows how you can learn something new each day :-) -
Nawaz almost 4 yearsI have an
IO String
and I want to map it toIO Int
and print theInt
. How do I do it in one line? Is that possible.