Ticket #2065 (closed bug: fixed)
QuickCheck: coarbitrary for Double and Float is broken.
The coarbitrary definition for these types is incompatible with the way they are generated. First, decodeFloat produces a pair (Integer, Int), then the Integer is manipulated to be positive and then coerced to an Int using fromInteger and passed to variant. Even 'simple' values of type Double and Float (as produced by arbitrary) can have huge significands. In the case of Double, the resulting Int can be negative due to truncation. This causes an exception when variant uses '(!!)' with a negative index. Huge positive values are just as bad since they cause a space leak while evaluating variant with a huge index (and tend not to terminate due to memory constraints). An obvious fix is to use the QuickCheck?-2 approach.
To reproduce, import Test.QuickCheck? and Text.Show.Functions, then run:
verboseCheck ((\f a -> f a == f a) :: (Float -> Int) -> Float -> Bool)
This should pass a few tests before finding a space leak.
verboseCheck ((\f a -> f a == f a) :: (Double -> Int) -> Double -> Bool)
This should also pass a few, then it may find a space leak, or it may error with:
*** Exception: Prelude.(!!): negative index
Note that QuickCheck?-2 has no problems here.