I have come across an exercise that asks us to write an instance of Semigroup for some data types and then test the associativity law with QuickCheck. During testing, however, I found that the Sum Double
instance always fails the test while other instances succeeded, for example String
and Sum Int
.
semigroupAssoc :: (Eq m, Semigroup m) => m -> m -> m -> Bool
semigroupAssoc a b c = (a <> (b <> c)) == ((a <> b) <> c)
main :: IO ()
main =
do
quickCheck (semigroupAssoc :: (Sum Double) -> (Sum Double) -> (Sum Double) -> Bool)
When I run the above code, the test always fails, for example with the following message:
*** Failed! Falsified (after 9 tests and 7 shrinks):
Sum {getSum = 1.0}
Sum {getSum = 3.0}
Sum {getSum = 0.924}
I guess the reason could be related to floating point precision or addition overflow (probably not this one as integer addition tests were fine)? But I cannot be sure about this because after searching the internet, I found nothing related to this. Could someone please expand a bit on this?