views:

91

answers:

2

Im trying to create a list of strings using some recursion.

Basically i want to take a part of a string up to a certain point. Create a list from that and then process the rest of the string through recursion.

type DocName = FilePath
type Line = (Int,String)
type Document = [Line]

splitLines :: String -> Document
splitLines [] = []
splitLines str | length str == 0 = []
                             | otherwise = zip [0..(length listStr)] listStr
                                    where 
                                        listStr = [getLine] ++ splitLines getRest
                                        getLine = (takeWhile (/='\n') str)
                                        getRest =  (dropWhile (=='\n') (dropWhile (/='\n') str))

Thats what i got. But it just concats the strings back together since they are list of characters themselves. But i want to create a list of strings.

["test","123"] if the input was "test\n123\n"

Thanks

+2  A: 

If you try to compile your code, you'll get an error message telling you that in the line

listStr = [getLine] ++ splitLines getRest

splitLines getRest has type Document, but it should have type [String]. This is easy enough to understand, since [getLine] is a list of strings (well a list of one string) and so it can only be concatenated with another list of strings, not a list of int-string-tuples.

So to fix this we can use map to replace each int-string-tuple in the Document with only the string to get a list of strings, i.e.:

listStr = [getLine] ++ map snd (splitLines getRest)

After changing the line to the above your code will compile and run just fine.

But it just concats the strings back together since they are list of characters themselves.

I'm not sure why you think that.

The reason your code did not compile was because of the type of splitLines as I explained above. Once you fix that error, the code behaves exactly as you want it to, returning a list of integer-string-tuples. At no point are strings concatenated.

sepp2k
ahh, ok. I was thinking of using map, just wasn't sure how.
Matt
+2  A: 

Well, if you wrote this just to practice recursion then it is fine once you fix error mentioned by sepp2k. But in real code, I would prefer -

splitLines str = zip [0..] (lines str)

Or even

splitLines = zip [0..] . lines
Matajon
Yea, we have to create our own code to read lines.
Matt