The current Arbitraryinstance used for testing Data.Setis too complex for my taste. I really do not understand this, so I do not believe it. I came up with the idea of separating form generation from value generation.
Using
class Monad m => MonadGen m where
liftGen :: Gen a -> m a
instance MonadGen Gen where
liftGen = id
instance MonadGen m => MonadGen (StateT s m) where
liftGen = lift . liftGen
I can write
mkArb :: MonadGen m => m a -> Int -> m (Set a)
mkArb step n
| n <= 0 = pure Tip
| n == 1 = singleton <$> step
| n == 2 = do
dir <- liftGen arbitrary
p <- step
q <- step
if dir
then pure (Bin 2 q (singleton p) Tip)
else pure (Bin 2 p Tip (singleton q))
| otherwise = do
let upper = (3*(n - 1)) `quot` 4
let lower = (n + 2) `quot` 4
ln <- liftGen $ choose (lower, upper)
let rn = n - ln - 1
(\lt x rt -> Bin n x lt rt) <$> mkArb step ln <*> step <*> mkArb step rn
Then I can use something like StateT s Gento populate the set with strictly ascending elements.
I have two questions: