I was trying to make Tic Tac Toe game for the monthly tutorial and wrote this code to make a box first:
box :: [String]
box = ["0 | 1 | 2",
"---------",
"3 | 4 | 5",
"---------",
"6 | 7 | 8"]
I get this output in GHCi:
["0 | 1 | 2\n","---------\n","3 | 4 | 5\n","---------\n","6 | 7 | 8\n"]
I wanted to get:
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
How can I print the grid like this?
Try something like:
box = unlines $ ["0 | 1 | 2",
"---------",
"3 | 4 | 5",
"---------",
"6 | 7 | 8"]
Then output the box using putStr
:
main = putStr box
What unlines
does is take a list of strings and join them together using newlines. It basically treats the list of strings as a list of lines and turns them into a single string.
putStr
just prints the string to STDOUT. If you used print
or GHCi to look at the string instead, newlines would be rendered as \n
rather than actual newlines. This happens because the show
instance of a String
is designed to serialize the string as you would have inputted it rather than printing it. Both print
and GHCi use show
before outputting to STDOUT.
If you are at the GHCi prompt and want to see what the string actually looks like, you can use putStr
directly:
*Main> putStr box
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
*Main>
Another approach is
main = mapM_ putStrLn box
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
is the analogue of map, but for monadic functions, its underscored cousin, mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
doesn't collect the return values and can thus be more efficient. If the return values are uninteresting, as for putStrLn s
, mapM_
is the better choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With