我寫了一個Haskell代碼,它必須解決以下問題:我們有n個文件:f1,f2,f3 .... fn和我剪切這些文件的方式每個切片具有100行如何使我的Haskell代碼使用懶惰和垃圾回收器
f1_1, f1_2, f1_3 .... f1_m
f2_1, f2_2, .... f2_n
...
fn_1, fn_2, .... fn_k
最後我構建使用切片以下列方式
f1_1, f2_1, f3_1, .... fn_1 => Dag1
f1_2, f2_2, f3_2, ..... fn_2 => Dag2
....
f1_k, f2_k, f3_k, ..... fn_k => Dagk
,我通過切割所有文件寫開始的代碼的特殊數據類型(DAG)的,那麼它結合結果列表的第i個元素並使用最終結果列表構建Dag
它看起來像這樣
-- # take a filename and cut the file in slices of 100 lines
sliceFile :: FilePath -> [[String]]
-- # take a list of lists and group the i-th elements into list
coupleIthElement :: [[String]] -> [[String]]
-- # take a list of lines and create a DAG
makeDags :: [String] -> Dag
-- # final code look like this
makeDag_ :: [FilePath] -> [Dag]
makeDags files = map makeDags $ coupleIthElement (concat (map sliceFile files))
的問題是,這個代碼是無效率的,因爲:
它需要儲存以列表的形式在內存中的所有文件
垃圾收集器不能有效地工作,因爲所有功能需要先前功能的結果列表
我該如何重新編寫程序以利用垃圾收集器工作和Haskell的懶惰?
如果不可能或更容易,我可以做些什麼來提高效率?
感謝答覆
編輯
coupleIthElement ["abc", "123", "xyz"]
必須返回["a1x","b2y","c3z"]
的100行是任意的在所述線的某些元件使用特定的標準來選擇,但我丟棄這方面使問題更容易理解,
另一個版本
data Dag = Dag ([(Int, String)], [((Int, Int), Int)]) deriving Show
test_dag = Dag ([(1, "a"),(2, "b"),(3, "c")],[((1,2),1),((1,3),1)])
test_dag2 = Dag ([],[])
第一列表是每個頂點由數量和標籤界定,第二列表是邊緣((1,2),3)
裝置頂點1和2之間的邊緣與成本3
是否有重要的關於100線分組,還是這是隨意的? – 2010-09-17 06:33:16
你的「sliceFile」類型沒有任何意義:當然它必須返回「IO [[String]]」 – 2010-09-17 06:33:49
ByteStrings是否可以工作而不是字符串?那樣會更有效率。 – 2010-09-17 06:35:44