[Haskell] combining IntMaps
Daan Leijen
daan at cs.uu.nl
Sat Jul 30 14:07:12 EDT 2005
Adrian Hey wrote:
> Hello,
>
>>Thanks! It's interesting the way your AVL tree library is set up --
>>there seems to be a much broader degree of functionality than that
>>provided by Data.Set. But I'm trying to see, is there a significant
>>difference in the fundamental data structure.
>
> Well Data.Set is based on a different balanced tree type (weight
> balanced trees), similar to those used in the Adams paper. I'm
> also quite sceptical about the Hedge algorithm, so the AVL library
> doesn't use it. It uses divide and conquer, but not quite as Adams
> describes it.
Please note that the original mail was about "IntMap" and "IntSet" and these data
structures use patricia trees and have a much different union algorithm alltogether.
(a very good one actually -- one of the main reasons to make a special Map and Set
instance for integers :-) )
> But IMO the biggest problem with Data.Set is the inflexible API.
> For example..
>
>>From Data.Set:
> union :: Ord a => Set a -> Set a -> Set a
> intersect :: Ord a => Set a -> Set a -> Set a
>
>>From Data.Tree.AVL:
> genUnion :: (e -> e -> COrdering e) -> AVL e -> AVL e -> AVL e
> genIntersection :: (a -> b -> COrdering c) -> AVL a -> AVL b -> AVL c
You are right, but there is a reason for this: with the Set api I wanted to expose
only operations that do not violate the notion of a mathematical set: ie. the
ordering on the elements must be fixed or otherwise the invariants might not hold any
longer. One way to insure this is by passing an ordering function when constructing a
set, but a nicer way is to use overloading (since only a single instance can hold for
the set).
Of course, maybe it is a good idea to make two modules: a 'collection' data type that
exposes internal operations, and a 'Set' module on top that implements sets and does
not expose operations that could violate set invariants.
You are right that these considerations do not make as much sense in the context of
general AVL trees since no guarantee op "Set" functionality is given there. Same
holds for the IntMap and Map interfaces. (but not for "Bag").
> or is the main point that
> the additional functionality could not have otherwise been provided in
> an efficient way without going into the guts of Data.Set?
Efficiency wise, I think one should only provide functions that ensure that the
complexity does not get worse -- if one also considers functionality that improves on
a constant factor (like traversing twice) there is no end to the number of functions
that can be provided (as one is basically doing deforestation by hand). But this is
of course just my personal opinion on how to control the size of the API.
All the best,
-- Daan Leijen.
> Of course there's no reason why similar functions could not be
> provided by Data.Set, but they're not there at present.
>
>
>>or is the main point that
>>the additional functionality could not have otherwise been provided in
>>an efficient way without going into the guts of Data.Set?
>
>
> Yes. This why producing useable libraries like this is so difficult.
> There's plenty of reasonable things you just can't do efficiently
> with Data.Set. Same is probably true of Data.Tree.AVL of course, but
> I'm trying to make it more complete all the time.
>
> Anyway, please try out AVL and let me know if there's anything more
> missing.
>
> Regards
> --
> Adrian Hey
>
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
More information about the Haskell
mailing list