
On Fri, Feb 18, 2011 at 3:32 PM, Johan Tibell
On Thu, Feb 17, 2011 at 4:51 PM, Johan Tibell
wrote: My current thinking is to provide lazy and strict versions in different modules. The two modules could still share the same data type. The question is, what should be the default? Haskell is a lazy language but the most common use cases for maps are strict (e.g. a map from strings to integer counters).
What about class instances? With a shared data type we can only provide one set of instances, probably the lazy ones. Assuming we used to separate data types, can we even define instances for all common classes (e.g. Functor, Foldable, Monoid) or will the strict versions violate some of the laws for these classes?
Hrmm, the strict version will violate the laws for Functor: (fmap (const 12) . fmap error) /= fmap (const 12 . error) and strictness is irrelevant for Monoid and Foldable as the former would be grafting trees that already contain forced values, and the Foldable instance only evaluates hashmaps, it doesn't produce them. Traversable doesn't have laws explicitly stated, but the fmapDefault it generates would violate the Functor laws given a strict map, indicating something isn't kosher with a strict traversable either. So it would seem at first glance, no (valid) instances are affected for stock classes. Now, I have some more ad-hoc methods in my 'keys' package which might have their behavior affected by the strict/lazy divide since I don't provide a full suite of laws for them (they provide some generic insert, adjust, etc. properties that i wanted for manipulating representable functors). But, if you split the types, you probably still want to allow users to splash a bit of laziness/strictness in turn, so it would seem you'd wind up with 2 types, 4 modules, and a lot of boilerplate. Ick. -Edward Kmett Johan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries