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

前端 未结 6 1332
遥遥无期
遥遥无期 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:57

    That looks like an understandable solution and you can clean it up slightly more:

    import Data.Map (toList, fromListWith)
    import Control.Arrow (second)
    
    convertKVList :: Ord a => [(a, b)] -> [(a, [b])]
    convertKVList = toList . fromListWith (++) . map (second (:[]))
    

    Regarding how you might come up with this on your own: assuming you started with Data.Map, then you want to use the map to combine values with equal keys. The documentation for Data.Map on Hackage says a is the type for values and k for keys.

    Knowing this, you can search for a -> a -> a to find functions that might combine two values in a Map k a to produce a new a value. This narrows the API down to a handful of functions like insertWith, fromListWith, and fromAscListWith.

    Similarly, to convert your Map k a to [(k, a)], you can search the documentation for Map k a -> [(k, a)] and find only a few functions like assocs, toList, toAscList, and toDescList. Note that in your case, [(k, a)] is instantiated to [(Int, [Int])].

    One thing I've found helpful in understanding the standard Haskell libraries is to view the source on Hackage. Seeing which functions are implemented in terms of others helps make the API feel smaller, and I can see which functions are the basic building blocks.

提交回复
热议问题