Haskell对数和列表

时间:2014-12-09 10:07:32

标签: list haskell recursion

我有问题。我有一项无法自行解决的任务。这是交易:

extPair :: Eq a => [(a,b)] -> [(a,[b])]    

如果我想用以下方式打电话:

extPair [(3,"pear"),(3,"fog"),(4,"dog"),(4,"x"),(3,"y")]

应该给出以下结果:

[(3, ["pear", "fog"]), (4, ["dog", "x"]), (3, ["y"])] :: [(Integer, [[Char]])]

我现在所知道的是:

extPair [] = []
extPair (x:xs)
 | length (x:xs) >= 2 && fst x == fst (head xs) = [(fst x, [snd x, snd (head xs)])] ++ extPair (drop 1 xs)
 | otherwise = [(fst x, [snd x])]

这适用于该示例,但它不适用于以下内容,而且我不知道如何制作它,所以我请求您的帮助。我想添加尽可能多的对:

extPair [(3,"pear"),(3,"fog"),(3,"dark"),(3,"etc"), ... ,(4,"dog"),(4,"x"),(3,"y"),(3,"z")]

所以结果应该是:

    [(3, ["pear", "fog", "dark", "etc", "...", "...", ...]), (4, ["dog", "x"]), (3, ["y", "z"])] :: [(Integer, [[Char]])]

2 个答案:

答案 0 :(得分:3)

使用foldr函数的另一种解决方案:

extPair :: Eq a => [(a,b)] -> [(a,[b])]
extPair = foldr f []
  where
    f (key, elem) [] = [(key, [elem])]
    f (key1, elem) l@((key2, elems):xs)
      | key1 == key2 = (key2,elem:elems):xs
      | otherwise    = (key1,[elem]):l

答案 1 :(得分:1)

您可以先使用groupBy预处理列表:

> import Data.List
> import Data.Function
> groupBy ((==) `on` fst) [(3,"pear"),(3,"fog"),(4,"dog"),(4,"x"),(3,"y")]
[[(3,"pear"),(3,"fog")],[(4,"dog"),(4,"x")],[(3,"y")]]

从那里开始,使用map f获取合适的f


如果您想编写自己的代码,请考虑递归:

extPair ((n,s):xs) = ???
   where ys = extPair xs

此处的逻辑如下:如果ys(n,zs)开头,则将s添加到zs,否则将(n,[s])添加到ys }。