-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Hi there!
First of all, thank you for creating and maintaining this library—I really appreciate the work that has gone into it!
While experimenting, I happened to notice that Sum Natural is an instance of Group, which caught me by surprise. Since the natural numbers under addition don’t form a group, I was curious about the reasoning behind this instance.
Looking at the laws stated in this library, the law a <> invert a == mempty doesn’t hold for any non-zero value of Sum Natural, since applying invert to a non-zero value results in an arithmetic underflow exception. That behaviour is understandable given that, for historical reasons, base defines Natural as an instance of Num, and that the Group instance for Sum a is currently defined as:
instance Num a => Group (Sum a) where
invert = Sum . negate . getSumOne could argue that the decision (presumably made long ago!) to make Natural an instance of Num was questionable, since this means the Num laws can’t always be strictly relied upon. Though given the mathematical focus of the groups library, I wonder whether maintaining this behaviour is the best approach?
Some other libraries have made a choice to avoid relying on the customary Num laws always holding. For example, in monoid-subclasses, Sum Natural is an instance of PositiveMonoid, but Sum Integer is not.
Perhaps a similar approach could be taken here? I suppose that one solution might be to introduce a helper class, such as:
class Num a => SumGroup a
instance SumGroup Int
instance SumGroup Int8
instance SumGroup Int16
instance SumGroup Int32
instance SumGroup Int64
instance SumGroup Integer
...Then, the constraints for the Group instance of Sum a could be strengthened:
instance SumGroup a => Group (Sum a)This would have the advantage of allowing types to be added on a case-by-case basis (and giving downstream users the flexibility to take the same measured approach for their own types). The downside, of course, is that making this change would require some caution to avoid breaking existing code.
I’d love to hear your thoughts on this. Thanks again for all your work on this library.
Best regards,
Jonathan