2009-05-05 33 views
4

基本上我需要做的是編寫一個函數,它需要一個類型爲[(String, String)]的列表並打印出內容,以便逐行輸出看起來像這:Haskell:打印出元組列表的內容

FirstString : SecondString 

FirstString : SecondString 

..等,列表中的每個項目。我得到了以下代碼並將其打印出來,但出於某種原因,它最後打印出包含[(),()]的行。

display :: Table -> IO() 
display zs = do { 
    xs <- sequence [putStrLn (a ++ " = " ++ b) | (a, b) <- zs]; 
    print xs 
} 

有什麼我做錯了嗎?

回答

10

最終打印xs是不必要的。這裏的序列返回一堆()s(putStrLn的返回值),並且print也將其打印出來。

當你在這,現在打印XS走了,你可以擺脫XS變量綁定,並使序列到sequence_扔掉的返回值,贈送:

display :: Table -> IO() 
display zs = sequence_ [putStrLn (a++" = "++b) | (a,b) <- zs] 
+2

如果內存是一個問題,你可能想要檢查newacct的方法(下面)。 – 2009-06-02 04:47:10

4

寫一個將元組轉換爲字符串的函數,可以根據需要進行格式化。
然後concatMap函數在你的列表上;打印結果。

8

你甚至可以使用mapM

display :: Table -> IO() 
display = mapM_ (\(a,b) -> putStrLn (a++" = "++b)) 
+1

該方法使用的內存少於bdonlan的方法。在我的樣本數據上,這個方法使用了大約70k。我不知道bdonlan的方法是否使用了更多的內存,因爲它必須創建一個IO操作列表。 – 2009-06-02 04:40:44

+1

你如何測量內存使用? Haskell創建一個/ lot /短暫的分配,所以它可能意味着這只是簡單的更快:) – bdonlan 2009-06-02 17:17:34

6

我將與JA同意,你應該在拆分您的代碼以兩個功能:

  • 一個部分:一個函數,你的數據結構並將它變成一個字符串
  • 一個不純部分,表示將該字符串呈現給控制檯

這裏有一個簡單的實現:

showTable :: Table -> String 
showTable xs = concatMap format xs 
    where 
    format (a, b) = a ++ " : " ++ b ++ "\n" 

display :: Table -> IO() 
display table = putStr (showTable table) 

這種設計有兩個好處:

原因之一,大部分的'邏輯」是在代碼中的滄海一粟,這是很好的,在一種功能性編程方式中。其次,這只是簡單的軟件工程原理;你現在有一個可以使用的可重用函數,如果你想要在你的代碼的另一部分格式化你的數據結構(看起來很可能)。