Haskell разбивает строки в список, включая пустые строки - PullRequest
1 голос
/ 29 сентября 2010

Так что имейте это

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

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

работает нормально, за исключением того, что, я думаю, мне тоже нужны пустые строки

splitLines "test\nthis\nstring\n" should be
[(0,"test"),(1,"this"),(2,"string"),(3,"")]

Не совсем уверен, как я мог это сделать. Есть идеи? Нужно ли переписать это с чем-то другим?

Должен ли я использовать функцию высокого порядка, например, Foldr? Спасибо.

Наконец-то понял, спасибо.

splitLines :: String -> Document
splitLines "" = [(0,"")]
splitLines str = zip [0..(length listStr)] listStr
                                    where 
                                        listStr = [getLine] ++ map snd (splitLines getRest)
                                        getLine = takeWhile (/='\n') str
                                        getRest = tail (dropWhile (/='\n') str)

Ответы [ 2 ]

2 голосов
/ 30 сентября 2010

Как уже упоминалось, вы не получите пустые строки, так как обрезаете символ новой строки вне начала строки.Было бы намного легче увидеть это, если бы splitLines был слегка изменен.Поскольку вы не можете использовать lines, я бы начал с создания простой функции split (вы также можете использовать Data.List.Split ):

split :: (Eq a) => a -> [a] -> [[a]]
split a [] = [[]]
split a lst = (\(xs, y:ys) -> [xs] ++ split a ys) $ break (==a) lst

С этой функциейsplitLines просто:

splitLines :: String -> Document
splitLines [] = []
splitLines str = zip [0..] $ split '\n' str 
2 голосов
/ 29 сентября 2010

Он отбрасывает пустые строки, потому что вы делаете dropWhile (=='\n) `, удаляя все разрывы строк в начале строки.

Чтобы оставить пустые строки, вы должны удалить только один разрыв строки.Самый простой способ сделать это - использовать сопоставление с образцом:

getRest = case (dropWhile (/='\n') str) of
              (_:xs) -> xs
              [] -> []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...