将元组列表按组排序

时间:2018-11-09 08:02:40

标签: sorting haskell grouping

我定义了一个类型:

type Sortable = [(String, Integer)]

我将根据字符串将它们分类。现在,我有:

funsort :: Sortable -> [Sortable] -> [Sortable]
funsort [] ret = ret
funsort ((name, value):xs) ret =
  let unsorted = (filter ((/=name).fst) xs) in
  let filtered = (filter ((==name).fst) xs) in
  let listofsortedlists = ((name,value) : homies) in
  funsort unsorted (ret : listofsortedlists)

在我看来,这应该可行,但事实并非如此。 :-/

我刚得到:

• Couldn't match type ‘(String, Value)’ with ‘[Sortable]’
  Expected type: [[Sortable]]
    Actual type: [(String, Value)]
• In the second argument of ‘(:)’, namely ‘sortedlistoflists’
  In the second argument of ‘funsort’, namely ‘(ret : sortedlistoflists)’
  In the expression: funsort unsorted (ret : sortedlistoflists)

1 个答案:

答案 0 :(得分:4)

您刚刚将参数的顺序切换为(:)

funsort :: Sortable -> [Sortable] -> [Sortable]
funsort [] ret = ret
funsort ((name, value):xs) ret =
  let unsorted = (filter ((/=name).fst) xs) in
  let filtered = (filter ((==name).fst) xs) in
  let listofsortedlists = ((name,value) : filtered) in
  funsort unsorted -- (ret : listofsortedlists)   -- wrong order
                   (listofsortedlists : ret)

毫无疑问,它与[]一起用作初始键值存储,

> funsort [("1",1), ("2",10), ("1",100)] []
[[("2",10)],[("1",1),("1",100)]]
it :: [Sortable]

通过命令列表来反向构建结果列表是更强制性的,非延迟的功能语言中的常见习惯用法。在Haskell中,由于懒惰,我们可以使用“ guarded” 递归以自上而下的方式构建列表:

funsort [] = []
funsort ((name, value):xs) =
  let unsorted = (filter ((/=name).fst) xs) in
  let filtered = (filter ((==name).fst) xs) in
  let listofsortedlists = ((name,value) : filtered) in
  listofsortedlists : funsort unsorted 

因此不需要多余的参数,并且结果以正确的顺序出现:

> funsort [("1",1), ("2",10), ("1",100)]
[[("1",1),("1",100)],[("2",10)]]

尽管如此,更有效的编码方式是通过Data.Map.Map String [Int]路由。留给您研究的乐趣。

cf。 FromList和朋友。