0

I'm trying to do this exercise in a book,

Define a function:

onSeperateLines :: [String] -> String

which takes a list of string and returns a single string which when printed shows the strings on separate lines.

I'm struggling with converting a list to a single string

onSeperateLines :: [String] -> String
onSeperateLines ls = [x | x <- ls]

I can write functions that take a String and convert it to a list and also a list that outputs a list, but I can't figure out how to take a list and convert it to a single string.

1 Answer 1

5

A String is nothing but a list of characters:

type String = [Char]

Hence,

onSeperateLines :: [[Char]] -> [Char]

Now, if you actually need this for some application, it's a good idea to first ask Hoogle if there's already something there. You get a whole lot of results:

unlines :: [String] -> String -- that's exactly the function you're trying to implement!
unwords :: [String] -> String -- similar, but only insert spaces, not newlines
joinPath :: [FilePath] -> FilePath -- Not relevant here
concat :: [[a]] -> [a] -- this does the general task of flattening a nested list to a simple one like a string.

concat is a good choice if you don't just want to use a standard function for the specific task, but also don't want to make life more difficult than necessary.

Of course, it also can't hurt to write a function like that once completely by yourself. To do that, you'll need to recursively deconstruct a list. This is extremely simple thanks to pattern matching:

onSeperateLines [] = ... --- no lines to concatenate... what's the result?
onSeperateLines (l:ls) = ...
 where otherLines = onSeperateLines ls

Think a little about what goes in these gaps.


The equivalent solution with foldr is also a good excercise.

Sign up to request clarification or add additional context in comments.

3 Comments

I've not used the (l:ls) notation before, if I entered a list of ["first","second","third"] how would I use 'l' to get the last two strings because 'ls' is a list and 'l' refers to the first string in the list doesn't it?
Another good one: intercalate, which easily generalizes unwords and unlines.
@W22: right. That's why you do a recursive call on ls: in one of these calls, any line will be the l once!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.