purescript-deprecated/purescript-strongcheck

add number newtype which produces examples of all kinds of numbers with edge cases

Closed this issue · 8 comments

In looking at generated numbers, I'm exclusively seeing fractions with a large number of decimals between 0 and 1. I feel that the algorithm should be robust enough to guarantee that the following cases are hit at least once:

Size Inty Floaty Pos Neg Known Case
Large Integral Positive 0
Small Deep Fractional Negative 1
Medium Shallow Fractional Infinity

so 23 varieties of cases

  1. Large Integral Positive (39458034958)
  2. Small Integral Positive (3)
  3. Medium Integral Positive (123)
  4. Large Deep Fractional Positive (20923409345.230948098234)
  5. Small Deep Fractional Positive (0.2904092834)
  6. Medium Deep Fractional Positive (345.2002934890845)
  7. Large Shallow Fractional Positive (203984209348.3)
  8. Small Shallow Fractional Positive (2.5)
  9. Medium Shallow Fractional Positive (594.56)
  10. Large Integral Negative (-12908092384)
  11. Small Integral Negative (-3)
  12. Medium Integral Negative (-234)
  13. Large Deep Fractional Negative (-902834098.8923479823)
  14. Small Deep Fractional Negative (-5.09238402334)
  15. Medium Deep Fractional Negative (-455.092384092348)
  16. Large Shallow Fractional Negative (-92837987234.3)
  17. Small Shallow Fractional Negative (-3.2)
  18. Medium Shallow Fractional Positive (-324.5)
  19. 0
  20. 1
  21. -1
  22. Infinity
  23. -Infinity

Currently there only seems to be support for case 5

I'm not sure what "shallow" and "deep" mean here, but you can use newtypes to do this sort of thing.

I just mean the length of the decimal. 0.5 is a different case from 0.2342342234

Ok, I'm not sure about the use cases for those, but you can generate them using newtypes or just by using the Gen Functor instance.

Edit: I guess what I'm saying is that it shouldn't be the job of this library (in my opinion) to provide a generator for every conceivable subset of the reals.

Sure, but I think it really should just be the way Number is handled.

There is Positive, Negative, and NonZero. I believe an arbitrary Number will always fall into [0, 1]. I guess what's needed is a newtype which will produce reasonable and edge cases for all numbers -- fractional, whole, negative, small, and large and the edge cases. Using exponential falloff as well as hard coding some edge cases, this should be totally doable.

The reason why Arbitrary for Number always falls in [0, 1] is that usually code will be testing a range (most code can't handle truly arbitrary numbers), and it's pretty convenient to know that you get out something within that range so you can modify it. That said, I think there's a good set of use cases for a truly arbitrary number, as described above.

ok, I still think that checking Number should be the truely arbitrary as described, and that its more appropriate to have a newtype for [0,1] perhaps called Fraction.

I'm open to this to be more consistent with the way String is handled, albeit it would break some code (it could be in the next version of strongcheck).