
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}.
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? Claus