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.
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries (other) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Multiple |
Architecture | Multiple |