My question is why Float is not readily defined to be an instance of the Monoid type class ?
I mean what is against it ? Doesn't Floats have the identity element and if no why? Also the operations (*)
and (+)
are associative in the set of Floats, or ?
Asked
Active
Viewed 356 times
0

IPiiro
- 97
- 1
- 9
-
Well the question actually already partially contains the answer: what operation will you pick? There is no inherent better one. `Monoid` is defined for types where it makes sense to have a straight forward "correct" operation. – Willem Van Onsem Jul 20 '17 at 10:47
-
So because you could pick `(*)` and `(+)` as operation for it, it makes no sense ? Excuse me but I kinda don't really understand the problem – IPiiro Jul 20 '17 at 10:53
-
1@IPirro: the problem is that you can only define *one* instance per type. So if you pick `(+)`, you cannot pick `(*)` and vice versa. In mathematics, a monoid is a 3-tuple: `(S,+,e)` with `S` the set, `+` the operation, and `e` the identity. But there can be multiple monoids with the same set, operation and/or identity element. – Willem Van Onsem Jul 20 '17 at 10:56
-
1Ok so just to be correct, Integer and Double wouldn't also not be instances of the Monoid class ? Oh alright that explanation is good – IPiiro Jul 20 '17 at 10:58
-
1based on the query `:i Monoid`, I get that `[a]`, `Ordering`, `Maybe a`, and `a -> b` are monoids (as well as tuples given the elements of the tuples are monoids). So indeed, `Integer` is not a monoid. – Willem Van Onsem Jul 20 '17 at 10:59
-
@IPiiro: It's the same as with _Int_ or _Integer_. The reasons why _Int_ has no default Monoid instance is mentioned in every tutorial on Monoids. – Jogger Jul 22 '17 at 09:31
1 Answers
6
Which monoid is are you talking about? Sum? Product?
These are already available by wrapping the type with the newtype
Sum
or Product
. But you are correct that addition and multiplication are not associative for floating-point numbers. That's somewhat a different issue, however. The issue is that there's not an obvious "correct" monoid to choose by default.

Dietrich Epp
- 205,541
- 37
- 345
- 415
-
I know addition isn't associative for floating-point. Why isn't multiplication? Something about normalization or NaN? – dfeuer Jul 20 '17 at 18:35
-
2@dfeuer Consider something like `(x*y)*(1/y)`, compared to `x*(y*(1/y))`, where `x*y` is too large to fit in a float (ie, evaluates to Infinity). After you get to Infinity, dividing by y no longer gets you back to x. There are probably similar issues when `x*y` is simply large enough to lose the precision that `x` alone had, so that when you divide by `y` again you can't get back all the information `x` had, even though you land in the same neighborhood. – amalloy Jul 20 '17 at 19:57
-
1
-
1I want to emphasize that the decision not to give the numeric types `Monoid` instances is extremely subjective. The haskell ecosystem is by no means consistent if the rule is "only obviously correct instances, else newtype wrapper" `Maybe` and lists for instance both have equally obvious alternatives for instance. – jberryman Jul 20 '17 at 22:10
-
@jberryman: I can understand Maybe but lists are basically the free monoid for sets to begin with. – Dietrich Epp Jul 21 '17 at 04:40