views:

405

answers:

2

Hey. For a tutorial this week, one of the questions asks to create a function formatLines by using other functions formatLine and formatList, to format a list of lines.

My code looks like this;

type Line = String

formatLine :: Line -> String
formatLine l = l ++ "\n"

formatList :: (a -> String) -> [a] -> String
formatList f [] = []
formatList f xs = f (head xs) ++ formatList f (tail xs)

formatLines :: [Line] -> String
formatLines xs = formatList formatLine xs

The code seems (to me, at least) like it should work, but instead of creating a new line where "\n" is, \n gets appended to the string.

Any help would be greatly appreciated.

+8  A: 

That is because you are probably using print to print the result. Instead, use putStr. Observe:

Prelude> print "test\ntest\n"
"test\ntest"
Prelude> putStr "test\ntest\n"
test
test

Other than that, you can use pattern matching to write formatList without head and tail:

formatList :: (a -> String) -> [a] -> String
formatList f [] = []
formatList f (x:xs) = f x ++ formatList f xs

But there is actually no need to define formatList yourself, as it is identical to the fucntion concatMap:

formatList :: (a -> String) -> [a] -> String
formatList = concatMap

Combining all this, you can also just write (note that (++ "\n") is a section):

formatLines :: [String] -> String
formatLines = concatMap (++ "\n")

...which in turn is equivalent to unlines:

formatLines :: [String] -> String
formatLines = unlines
Stephan202
unlines, not unwords. Using either is not really in the spirit of following a tutorial, but +1 for pointing out what's already available.
Nefrubyr
@Nefrubyr: doh, you're right :)
Stephan202
A: 

Just try

formatLines = unwords
Dario