基本原则是您希望将“相似”元素组合在一起。
每当您想将元素组合在一起时,您都可以group
使用Data.List
. 在这种情况下,您希望自己指定什么是相似的,因此您需要使用该groupBy
版本。中的大多数函数Data.List
都有一个By
-version 版本,可让您更详细地指定所需内容。
第1步
在您的情况下,您希望将“相似性”定义为“具有相同的第一个元素”。在 Haskell 中,“在一对上具有相同的第一个元素”意味着
(==) `on` fst
换句话说,一对的第一个元素相等。
因此,为了进行分组,我们将该要求提供给groupBy
,如下所示:
groupBy ((==) `on` fst) xs
在您的示例中,这将使我们回到两组:
[[("a","b"),("a","c")]
,[("b","e")]]
第2步
现在剩下的就是将这些列表变成对。这背后的基本原则是,如果我们让
ys = [("a","b"),("a","c")]
例如,取第一对的第一个元素,然后将所有对的第二个元素一起粉碎成一个列表。取第一对的第一个元素很容易!
fst (head ys) == "a"
获取所有第二个元素也相当容易!
map snd ys == ["b", "c"]
这两个操作一起给了我们想要的东西。
(fst (head ys), map snd ys) == ("a", ["b", "c"])
完成的产品
所以如果你愿意,你可以把你的聚集函数写成
clump xs = (fst (head ys), map snd ys)
where ys = groupBy ((==) `on` fst) xs