Printing elements of a list on new lines

Haskell

Haskell Problem Overview


I am trying to print the elements of my list onto new lines, but i cant get it to work;

printElements :: [String] -> IO()
printElements (x:xs) =  print x (some kind of newline, then loop?) printElements xs

So this:

["1","2","2","4"]

would give:

1
2
3
4

Haskell Solutions


Solution 1 - Haskell

In most cases you don't need to program a loop over a list, it's been done already. To loop over a list with a monadic function, you would use mapM (and its mapM_ variant if you don't care about the result.)

If you use print, for ["1","2","3","4"] you'd get :

Prelude> mapM_ print ["1","2","3","4"]
"1"
"2"
"3"
"4"
Prelude> 

print is actually :

print :: Show a => a -> IO ()
print x = putStrLn (show x)

the show function causes the string "1" to be converted to "\"1\"", putStrLn prints that and a newline.

If you replace the print by putStrLn, you remove the conversion step and print directly the string:

Prelude> mapM_ putStrLn ["1","2","3","4"]
1
2
3
4
Prelude> 

Now I would like to offer another solution. The Haskell way of doing things is doing as much as you can in a pure way, and only use IO when you need it.

So in this case we can join all strings to be printed with a \n, and print all the strings at once.

To join all the strings there's a handy function : unlines

Prelude> unlines ["1","2","3","4"]
"1\n2\n3\n4\n"
Prelude> 

Now you just have to print that; notice that unlines put a newline after the last item of the list, so we'll use putStr instead of putStrLn

Prelude> putStr ( unlines ["1","2","3","4"] )
1
2
3
4
Prelude> 

Solution 2 - Haskell

Your function is:

printElements :: [String] -> IO()
printElements [] = return ()
printElements (x:xs) = do putStrLn x
                          printElements xs

If you already know about monads, you can use mapM_ function:

printElements :: [String] -> IO()
printElements = mapM_ putStrLn

Note: maybe you would have to read the chapter 8 of lyah.

Solution 3 - Haskell

Instead of explicit recursion, you can use mapM_ to call putStrLn for every element. It works like the regular map for lists, but is used with a monadic function (thus the "M"). The underscore variant is used when you only care about the side-effect (in this case, printing) and don't care about the result of the mapped function.

printElements :: [String] -> IO ()
printElements = mapM_ putStrLn

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLunarView Question on Stackoverflow
Solution 1 - HaskellDavid V.View Answer on Stackoverflow
Solution 2 - HaskellAlviviView Answer on Stackoverflow
Solution 3 - HaskellshangView Answer on Stackoverflow