
On Fri, Jul 9, 2010 at 4:18 PM, Claus Reinke
The idea would be to provide both IntMap and IntMap',
the latter being strict in the keys. There would be one
strict in the values, of course..
So instead of choosing between function' and function (doubling the API size) or between Data.IntMap.strict and Data.IntMap.nonstrict, clients would simply choose between IntMap' and IntMap (even a conversion could be offered - just another specialisation of map). This module is small enough that one can compare
the core output (-ddump-simpl), and it looks as if
the -O2 compiled core for the specialized versions of mapL matches that for the handcoded versions. No manual duplication, just pragmas, same code and API, just different types for the two use cases.
Since I don't have much practice reading core, it would
be good if those of you with more core experience could check this assertion; also on whether there is any reason to expect difficulties extending this to Data.{IntMap,Map}.
Honestly I think the code duplication is more likely to yield robust, fast code. It can be hard to make anything where the entire API goes through a huge dictionary generate well-performing core. foldl', foldr' and their ilk are common enough that folks are pretty comfortable with that convention. mapL :: (L l a,L l b) => (a -> b) -> l a -> l b
{-# SPECIALIZE mapL :: (a -> b) -> L1 a -> L1 b #-} {-# SPECIALIZE mapL :: (a -> b) -> L2 a -> L2 b #-}
If only the type-specialized maps would be exported
(with map instead of mapL and IntMap'/IntMap instead of L1/L2), neither the class nor the language pragmas would affect client code, so this could be a mostly compatible extension. I'm not sure how to do that without writing more code, though - any suggestions?
Providing an entire IntMap' seems fairly drastic. Now you wind up with a whole host of interoperability scenarios. It strikes me that the cure is worse than the disease. -Edward Kmett