2010-09-29 40 views
3

我試圖創建一個使用某種遞歸的字符串列表。Haskell - Concat的字符串列表

基本上我想取一個字符串的一部分到某一點。從中創建一個列表,然後通過遞歸處理字符串的其餘部分。

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)) 

那就是我得到的。但它只是將字符串連接在一起,因爲它們是字符本身的列表。但是我想創建一個字符串列表。

[「測試」,「123」]如果輸入是「測試\ N123 \ n」個

感謝

+0

你的意思是'[(1, 「測試」),(2, 「123」)]'對不對? 'Line'是一個元組,不只是一個String。 – kennytm 2010-09-29 17:52:17

+0

是的,但我專注於「listStr = [getLine] ++ splitLines getRest」那部分 – Matt 2010-09-29 17:56:28

+2

你的問題的標題很混亂 - 你不是試圖連接字符串,你想分開它們,這是相反的。 – Amoss 2010-09-29 18:36:32

回答

3

如果試圖編譯代碼,你會得到一個錯誤信息,告訴您在線路

listStr = [getLine] ++ splitLines getRest 

splitLines getRest的類型是Document,但它應該有類型[String]。這很容易理解,因爲[getLine]是一個字符串列表(以及一個字符串列表),所以它只能與另一個字符串列表連接,而不是一個int-string-tuples列表。

因此,要解決這個問題,我們可以使用地圖只有字符串替換文檔的每個INT-字符串元組獲得一個字符串列表,即:

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

轉產上述後你的代碼會編譯並運行得很好。

但它只是將字符串連接在一起,因爲它們是字符本身的列表。

我不確定你爲什麼這麼想。

你的代碼沒有編譯的原因是因爲我上面解釋過的splitLines的類型。一旦你修正了這個錯誤,代碼就會按照你想要的那樣運行,返回一個integer-string-tuples列表。在任何時候都不會串聯字符串。

+0

啊,好的。我正在考慮使用地圖,只是不知道如何。 – Matt 2010-09-29 18:31:47

3

那麼,如果你寫這個只是爲了練習遞歸,那麼一旦你修復了sepp2k提到的錯誤,那就沒事了。但在實際的代碼,我寧願 -

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

甚至

splitLines = zip [0..] . lines 
+0

是的,我們必須創建自己的代碼來讀取行。 – Matt 2010-09-29 18:51:48