2014-11-20 82 views
1

我試圖減少元組的列表,其中重複鍵的值加在一起是這樣的:哈斯克爾 - 減少列表 - MapReduce的

[(the, 1), (the, 1)] => [(the, 2)]

我嘗試這樣做:

reduce :: [(String, Integer)] -> [(String, Integer)] 
reduce [] = [] 
reduce [(k, v) : xs] = (+) [(k, v)] : reduce xs 

我得到這個錯誤:

Couldn't match expected type `(String, Integer)' 
      with actual type `[(String, Integer)] -> [(String, Integer)]' 

我在做什麼錯?

編輯

這是一個完整的程序

toTuple :: [String] -> [(String, Integer)] 
toTuple [] = [] 
toTuple (k:xs) = (k, 1) : toTuple xs 

reduce :: [(String, Integer)] -> [(String, Integer)] 
reduce [] = [] 
reduce [(k, v) : xs] = (+) [(k, v)] : reduce xs  

main_ = do list <- getWords "test.txt" 
     print $ reduce $ toTuple list 

-- Loads words from a text file into a list. 
getWords :: FilePath -> IO [String] 
getWords path = do contents <- readFile path 
       return ([Prelude.map toLower x | x <- words contents]) 
+0

什麼是(+)[(k,v)]'應該在做什麼? – bheklilr 2014-11-20 19:01:01

+0

另外,你的主要問題是'[(k,v):xs]'匹配一個包含單個元素的列表,即'(k,v):xs',你應該匹配'((k,v):xs )'而不是。 – bheklilr 2014-11-20 19:01:38

+0

@bheklilr它應該添加一個K的v是一樣的。我試圖複製這個'map_list = M.toList $ M.fromListWith(+)[(x,1)| x < - list]' – 2014-11-20 19:02:28

回答

1

你是做錯誤的匹配模式。模式匹配應該是這樣的:

((k,v):xs) 

(k,v)代表名單的頭和xs表示列表的尾部。同樣的,這是有問題的:

(+) [(k, v)] : reduce xs 

類型的+是這樣的:

λ> :t (+) 
(+) :: Num a => a -> a -> a 

你不能簡單地做(+) [(k, v)] : reduce xs不任何地方出現合理。您必須檢查字符串的內容,然後添加元組的第二部分。

+0

但是我傳遞了一個元組列表。看我的編輯。 – 2014-11-20 19:07:46

+0

@AdegokeA如果你傳遞元組列表,你期望什麼? – Sibi 2014-11-20 19:09:23

+0

我期望得到一個元組列表,但沒有重複的鍵,而是我想要一個具有更新值的鍵。就像我在我的問題中給出的例子。 – 2014-11-20 19:11:13