Haskell: converting a list of (a, b) key-value pairs (with possibly repeated keys) to a list of (a, [b]) grouped by key

前端 未结 6 1337
遥遥无期
遥遥无期 2021-01-01 17:13

I\'m a Haskell beginner. Let\'s suppose I want to write a function convertKVList that takes a flat list of key-value pairs, where some of the keys might be rep

6条回答
  •  清歌不尽
    2021-01-01 17:56

    Hoogle is not the only search engine able to search Haskell libraries by type signatures and it definitely and unfortunately covers only a small part of Hackage. Searching with Hayoo for a type signature [(a,b)]->[(a,[b])] brought up these two implementations:

    • aggregateAL
    • alistCollect

    Concerning your take on the problem, since in your function you already bring up a higher level datastructure (Map), it doesn't make sense to downgrade to a more primitive associative list in the output, because:

    1. Most of the algorithms you can possibly utilize such data in will only benefit from getting a Map input, because it's much more effective for dealing with key-value stores, and if you ever find yourself still needing a list you can always utilize the toList in place.
    2. Map implies the absence of duplicate keys on type level, which is not any less important, since in Haskell you should always do the maximum proofs using the type-system. This principle is essentially what makes the statement "If it compiles, it works" closest to truth.

    In other words this is the correct definition of your function:

    convertKVList :: (Ord a) => [(a, b)] -> Map a [b]
    convertKVList ls =
      Map.fromListWith (++) . map (\(x,y) -> (x,[y])) $ ls
    

    Hayooing for that type signature brings a couple of already implemented results too.

    Concerning the approaching the problem, it's classic: "Divide and conquer!". Chris has some good points too in his answer.

提交回复
热议问题