
I've just been looking at the Data.Map function "fromListWith". According to the docs, it has the type: * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> a -> a) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k a I'd have thought that a better type would be * fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> b -> b) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k b This wouldn't break any existing code, but would allow things like "fromListWith (:)" to do the Right Thing. Would this be a sensible change (along with the other "with" functions in the module). Paul.

On Sat, Dec 6, 2008 at 12:22 PM, Paul Johnson
I've just been looking at the Data.Map function "fromListWith". According to the docs, it has the type:
* fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> a -> a) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k a
I'd have thought that a better type would be
* fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> b -> b) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k b
This wouldn't break any existing code, but would allow things like "fromListWith (:)" to do the Right Thing.
Would this be a sensible change (along with the other "with" functions in the module).
Paul.
Hi, I don't think that type makes sense. fromListWith takes a list of [(key,value)] and a combining function to combine the values when there are multiple pairs with the same key. Thus, a type of (a -> b -> b) for the combining function doesn't make sense because the values are all going to have the same type (i.e. they are all "a"s). We might consider (a -> a -> b), but this doesn't make sense either because then you have some values with type "a" (the ones that didn't need to be combined) and some with type "b" (the ones that were combined). (a -> a -> a) is really the only type that works. I don't think fromListWith (:) makes sense either. (:) :: a -> [a] -> [a], so you would end up with some values of the map as individual items and others as lists of items. All of the values need to have the same type. Regards, Alex

On Sat, Dec 6, 2008 at 12:22 PM, Paul Johnson
wrote: I've just been looking at the Data.Map function "fromListWith". According to the docs, it has the type:
* fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> a -> a) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k a
I'd have thought that a better type would be
* fromListWith* :: Ord http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Ord.html#t%3... k => (a -> b -> b) -> [(k, a)] -> Map http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.ht... k b
This wouldn't break any existing code, but would allow things like "fromListWith (:)" to do the Right Thing.
Would this be a sensible change (along with the other "with" functions in the module).
Paul.
Hi,
I don't think that type makes sense. fromListWith takes a list of [(key,value)] and a combining function to combine the values when there are multiple pairs with the same key. Ahh yes. I was thinking that the job of fromListWith was analogous to foldr, but carrying out the fold on a per-key basis. However I see now
Alexander Dunlap wrote: that it is more like foldr1 than foldr because foldr needs a zero value. So we could have fromListWithZero :: Ord k => (a -> b -> b) -> b -> [(k, a)] -> Map k b fromListWithZero combiner zero pairs = ... The first time a key is seen the combining function is called with "zero" as its second argument. E.g. fromListWithZero (:) [] xs Or is that too much trouble? Accumulating a collection of lists is the most obvious use of this function, and you can do that already (albeit rather clunkily) with fromListWith (++) $ map (\(k,v) -> (k, [v]) $ xs The only time that fromListWithZero would be especially useful is when you want the fold to be eager. Paul.

On Saturday 06 December 2008 22:07:51 Paul Johnson wrote:
So we could have
fromListWithZero :: Ord k => (a -> b -> b) -> b -> [(k, a)] -> Map k b fromListWithZero combiner zero pairs = ...
The first time a key is seen the combining function is called with "zero" as its second argument. E.g.
fromListWithZero (:) [] xs
Or is that too much trouble?
It could be made a bit more general and efficient: Every entry x that did not have to be combined with another will end up as an application (combiner zero x). Thus, you could also write a function fromListWithUnit :: Ord k => (a -> b -> b) -> (a -> b) -> [(k, a)] -> Map k b fromListWithUnit combiner unit pairs = ... and define fromListWithZero via fromListWithZero c z ps = fromListWithUnit c (c z) ps But there is fromListWithUnit c u = fromListWith c . map (\p ->(fst p, u (snd p))) So, you already have what you want. Regards, Holger
participants (3)
-
Alexander Dunlap
-
Holger Siegel
-
Paul Johnson