benwad
benwad

Reputation: 6594

Haskell: Printing out the contents of a list of tuples

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

Answers (4)

Tom Lokhorst
Tom Lokhorst

Reputation: 13768

I would agree with ja that you should split up your code in to two functions:

  • A pure part: a function that takes your data structure and turns it into a string
  • An impure part, that renders that string to the console

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

newacct
newacct

Reputation: 122489

You could even use mapM:

display :: Table -> IO ()
display = mapM_ (\(a,b) -> putStrLn (a++" = "++b))

Upvotes: 8

ja.
ja.

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

bdonlan
bdonlan

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

Related Questions