
Hi
The main difference is a pretty comprehensive interface shakeup: the Either variants have been dropped, all L variants have had the L removed from their name, and a few functions have been curried. The end result is an interface much closer to that of Data.Map. (This also means that 0.2 isn't backwards-compatible.)
Good, this seems much nicer. A few comments: 1) You depend on MTL, but I can't obviously see why. Perhaps the test suite? 2) The code: {-| Insert a pair of values into the bimap, without checking for overlapping bindings. If either value is already in the bimap, and is not bound to the other value, the bimap will become inconsistent. -} unsafeInsert :: (Ord a, Ord b) => a -> b -> Bimap a b -> Bimap a b unsafeInsert x y (MkBimap left right) = MkBimap (M.insert x y left) (M.insert y x right) To my understanding, this is always safe, since insert will overwrite any existing element in a map. Hence you don't need to do the delete's first. In addition, since Bimap is not exported internally, the invariant will never be violated. 3) insert x y = delete x >>> deleteR y >>> unsafeInsert x y Why not: insert x y = unsafeInsert x y . delete x . delete y Now you don't end up using the arrow combinators, and it becomes more readable (at least to me). Of course, this function may disappear entirely if what I wrote in (2) is correct. I will probably start using the bimap package in my current project, so you already have at least one user :-) Thanks Neil