Reputation: 6594
Basically what I need to do is write a function that takes in a list of type [(String, String)]
and prints out the contents so that, line-by-line, the output looks like this:
FirstString : SecondString
FirstString : SecondString
..etc, for every item in the list. I've got the following code and it prints it out, but for some reason it prints out a line containing [(),()]
at the end.
display :: Table -> IO ()
display zs = do {
xs <- sequence [putStrLn ( a ++ " = " ++ b) | (a, b) <- zs];
print xs
}
Is there anything I'm doing wrong?
Upvotes: 5
Views: 9105
Reputation: 13768
I would agree with ja that you should split up your code in to two functions:
Here's a simple implementation:
showTable :: Table -> String
showTable xs = concatMap format xs
where
format (a, b) = a ++ " : " ++ b ++ "\n"
display :: Table -> IO ()
display table = putStr (showTable table)
This design has two advantages:
For one, most of your `logic' is in the pure part of the code, which is nice, in a functional programming kind of way.
Secondly, and this is just simple software engineering principle; you now have a reusable function that you can use, should you ever want to format your data structure in another part of your code (seems likely).
Upvotes: 6
Reputation: 122489
You could even use mapM
:
display :: Table -> IO ()
display = mapM_ (\(a,b) -> putStrLn (a++" = "++b))
Upvotes: 8
Reputation: 4249
Write a function that takes a tuple to a string, formatted as you wish.
Then concatMap that function over your list; print the result.
Upvotes: 4
Reputation: 231273
The final print xs is unnecessary. sequence here is returning a bunch of ()s (the return value of putStrLn), and print is printing that out as well.
While you're at it, now that print xs is gone, you can get rid of the xs variable binding, and make sequence into sequence_ to throw away the return value, giving:
display :: Table -> IO()
display zs = sequence_ [putStrLn (a++" = "++b) | (a,b) <- zs]
Upvotes: 10