2014-11-20 75 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