Why not use smallcheck?
turion:
For your specific example, for a threshold of 18,
tinycheckfinds the bug after less than 2 million (and more than 200 000) values, which takes 0.3 seconds on my machine. (1.4 seconds for a threshold of 20, still less than 2 million values.) I agree that this is probably less performant than QuickCheck, but still I find it noteable. I achieved it by just writing down the basic idea behind SmallCheck from memory in little time as a library. This says something about the power of the idea.
You asked me about SmallCheck, not about your library. Here is a test suite I based my previous answer on:
#!/usr/bin/env cabal
{- cabal:
build-depends: base, tasty, tasty-smallcheck
default-language: GHC2021
-}
import Test.Tasty
import Test.Tasty.SmallCheck
import Data.List (sort)
main = defaultMain $
-- depth 19 means that we are building lists of length 0..18
localOption (SmallCheckDepth 19) $
testProperty "mySort matches the reference implementation" $
\xs -> mySort xs == sort xs
mySort :: [Int] -> [Int]
mySort xs
| length xs < 18 = sort xs
| otherwise = error "explode"
This completed ~65000 of tests in 10 minutes on my machine and does not seem to be anywhere near the counterexample. If your library completes 200000+ tests in 0.3 seconds (which is roughly 6000 times faster), that’s a great result, but it does not relate to SmallCheck.
Discussion in the ATmosphere