{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.GenValidity.Set
( genSetOf,
genSeperate,
genSeperateFor,
genSeperateForNE,
genValidSeperateFor,
genValidSeperateForNE,
)
where
import Data.Containers.ListUtils
import Data.GenValidity
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Set (Set)
import qualified Data.Set as S
import Data.Validity.Set ()
import Test.QuickCheck
instance (Ord v, GenValid v) => GenValid (Set v) where
genValid = S.fromList <$> genValid
shrinkValid = fmap S.fromList . shrinkValid . S.toList
genSetOf :: Ord v => Gen v -> Gen (Set v)
genSetOf g = S.fromList <$> genListOf g
genValidSeperateFor :: (GenValid b, Eq b) => [a] -> Gen [(b, a)]
genValidSeperateFor = genSeperateFor genValid
genValidSeperateForNE :: (GenValid b, Eq b) => NonEmpty a -> Gen (NonEmpty (b, a))
genValidSeperateForNE = genSeperateForNE genValid
genSeperate :: Ord a => Gen a -> Gen [a]
genSeperate g = nubOrd <$> genListOf g
-- TODO these two can likely be optimised
genSeperateFor :: Eq b => Gen b -> [a] -> Gen [(b, a)]
genSeperateFor _ [] = pure []
genSeperateFor g (a : as) = NE.toList <$> genSeperateForNE g (a :| as)
genSeperateForNE :: Eq b => Gen b -> NonEmpty a -> Gen (NonEmpty (b, a))
genSeperateForNE g (a :| as) = do
restTups <- genSeperateFor g as
b <- g `suchThat` (`notElem` map fst restTups)
pure ((b, a) :| restTups)