1

Trying to learn Haskell and stumbled upon this:

Prelude> import Data.Semigroup
Prelude Data.Semigroup> let x = Sum 0.1 <> Sum 0.2 <> Sum 0.3
Prelude Data.Semigroup> let y = (Sum 0.1 <> Sum 0.2) <> Sum 0.3
Prelude Data.Semigroup> x == y
False

Obviously that's the normal inaccuracy with floating point arithmetic, but why are floating point values instances of Num or perhaps why is there an instance instance Num a => Semigroup (Sum a) if associativity doesn't hold? Are there any other areas where the guarantees of the type system aren't guarantees that one should be aware of? Besides fixed-width numerical values?

HBu
  • 559
  • 6
  • 18
  • 6
    Unfortunately (or fortunately, depends how you look at it) laws attached to type classes aren't checked by the type system (doing that would require a theorem solver). – Alec Aug 21 '17 at 21:03
  • 3
    Probably pragmatics trumped exactness here. Not having a working `Sum Double` might be considered worse than having a "working" one which ignores rounding errors. – chi Aug 21 '17 at 21:58
  • 4
    You can think of it from this alternative point of view: the law `(a <> b) <> c = a <> (b <> c)` doesn't specify which equality should be used, i.e. what specific relation the `=` denotes. It is natural to think of it in terms of structural equality, but note that very few typeclass laws actually hold up to structural equality (e.g. try proving `fmap id = id` for `[]` as opposed to `forall x . fmap id x = id x`). For this case, you could think of the `=` as an equality which judges `Double`s to be equal if the absolute value of their difference is less than machine epsilon. – user2407038 Aug 21 '17 at 22:56

0 Answers0