将子列表值基于与Haskell的等效总和

时间:2012-03-30 20:30:23

标签: haskell

我正在尝试学习Haskell,我正在尝试创建一个函数,该函数采用列表并按等效总和对子列表进行分组。这不是作业。

import Data.List
let x = [[1,2],[2,1],[5,0],[0,3],[1,9]]
let groups = groupBy (\i j -> sum i == sum j) x

我在GHCi中得到了这个输出:

[[[1,2],[2,1]],[[5,0]],[[0,3]],[[1,9]]]

我将[[1,2],[2,1]]分组在一起,但不与[0,3]分组。这是为什么?

我怀疑我需要使用map,但我似乎无法使其发挥作用。

2 个答案:

答案 0 :(得分:4)

groupBy将列表拆分为满足给定谓词的相邻元素的块。由于在您的情况下,[0,3][1,2][2,1]分开,因此第一组仅包含这些内容。要将具有相同总和的列表的所有元素收集到一个组中,您需要进行一些预处理,例如:与sortBy

import Data.List
import Data.Function
import Data.Ord

groupBySum :: Num a => [[a]] -> [[[a]]]
groupBySum xss = groups
  where
    ys = map (\xs -> (sum xs,xs)) xss
    sortedSums = sortBy (comparing fst) ys
    groupedSums = groupBy ((==) `on` fst) sortedSums
    groups = map (map snd) groupedSums

答案 1 :(得分:3)

来自hackage

  

group函数接受一个列表并返回一个列表列表,使得结果的串联等于参数。

groupBy是相同的,除了您可以指定您的相等测试。因此,由于在您的输入列表中[0,3][1,2][2,1]不相邻,因此它会自行放置。