@@ -21,6 +21,7 @@ import Data.List.NonEmpty (NonEmpty(..))
2121import qualified Data.List.NonEmpty as NE
2222
2323import Utils.ArbitrarySetMap (mkArbSet , setFromList )
24+ import Utils.ArbitraryInstances ()
2425
2526main :: IO ()
2627main = defaultMain $ testGroup " set-properties"
@@ -192,94 +193,34 @@ test_deleteAt = do
192193 Arbitrary, reasonably balanced trees
193194--------------------------------------------------------------------}
194195
195- -- | The IsInt class lets us constrain a type variable to be Int in an entirely
196- -- standard way. The constraint @ IsInt a @ is essentially equivalent to the
197- -- GHC-only constraint @ a ~ Int @, but @ IsInt @ requires manual intervention
198- -- to use. If ~ is ever standardized, we should certainly use it instead.
199- -- Earlier versions used an Enum constraint, but this is confusing because
200- -- not all Enum instances will work properly for the Arbitrary instance here.
201- class (Show a , Read a , Integral a , Arbitrary a ) => IsInt a where
202- fromIntF :: f Int -> f a
203-
204- instance IsInt Int where
205- fromIntF = id
206-
207- -- | Convert an Int to any instance of IsInt
208- fromInt :: IsInt a => Int -> a
209- fromInt = runIdentity . fromIntF . Identity
210-
211- {- We don't actually need this, but we can add it if we ever do
212- toIntF :: IsInt a => g a -> g Int
213- toIntF = unf . fromIntF . F $ id
214-
215- newtype F g a b = F {unf :: g b -> a}
216-
217- toInt :: IsInt a => a -> Int
218- toInt = runIdentity . toIntF . Identity -}
219-
220-
221- -- How much the minimum value of an arbitrary set should vary
222- positionFactor :: Int
223- positionFactor = 1
224-
225- -- How much the gap between consecutive elements in an arbitrary
226- -- set should vary
227- gapRange :: Int
228- gapRange = 5
229-
230- instance IsInt a => Arbitrary (Set a ) where
231- arbitrary = sized (\ sz0 -> do
232- sz <- choose (0 , sz0)
233- middle <- choose (- positionFactor * (sz + 1 ), positionFactor * (sz + 1 ))
234- let shift = (sz * (gapRange) + 1 ) `quot` 2
235- start = middle - shift
236- t <- evalStateT (mkArbSet step sz) start
237- if valid t then pure t else error " Test generated invalid tree!" )
238- where
239- step = do
240- i <- get
241- diff <- lift $ choose (1 , gapRange)
242- let i' = i + diff
243- put i'
244- pure (fromInt i')
245-
246196data TwoSets = TwoSets (Set Int ) (Set Int ) deriving (Show )
247197
248- data TwoLists a = TwoLists [a ] [a ]
249-
250- data Options2 = One2 | Two2 | Both2 deriving (Bounded , Enum )
251- instance Arbitrary Options2 where
252- arbitrary = arbitraryBoundedEnum
253-
254198-- We produce two lists from a simple "universe". This instance
255199-- is intended to give good results when the two lists are then
256200-- combined with each other; if other elements are used with them,
257201-- they may or may not behave particularly well.
258- instance IsInt a => Arbitrary (TwoLists a ) where
259- arbitrary = sized $ \ sz0 -> do
260- sz <- choose (0 , sz0)
261- let universe = [0 ,3 .. 3 * (fromInt sz - 1 )]
262- divide2Gen universe
263-
264202instance Arbitrary TwoSets where
265203 arbitrary = do
266- TwoLists l r <- arbitrary
204+ (l, r) <- sized $ \ sz0 -> do
205+ sz <- choose (0 , sz0)
206+ let universe = [0 ,3 .. 3 * (sz - 1 )]
207+ divide2Gen universe
267208 TwoSets <$> setFromList l <*> setFromList r
268-
269- divide2Gen :: [a ] -> Gen (TwoLists a )
270- divide2Gen [] = pure (TwoLists [] [] )
271- divide2Gen (x : xs) = do
272- way <- arbitrary
273- TwoLists ls rs <- divide2Gen xs
274- case way of
275- One2 -> pure ( TwoLists (x : ls) rs)
276- Two2 -> pure ( TwoLists ls (x : rs))
277- Both2 -> pure ( TwoLists (x : ls) (x : rs))
209+ where
210+ divide2Gen :: [a ] -> Gen ([ a ], [ a ] )
211+ divide2Gen [] = pure ([] , [] )
212+ divide2Gen (x : xs) = do
213+ mIsFirst <- arbitrary
214+ (ls, rs) <- divide2Gen xs
215+ pure $ case mIsFirst of
216+ Just True -> ( (x : ls), rs)
217+ Just False -> (ls, (x : rs))
218+ Nothing -> ( (x : ls), (x : rs))
278219
279220{- -------------------------------------------------------------------
280221 Valid trees
281222--------------------------------------------------------------------}
282- forValid :: (IsInt a , Testable b ) => (Set a -> b ) -> Property
223+ forValid :: (Testable b ) => (Set Int -> b ) -> Property
283224forValid f = forAll arbitrary $ \ t ->
284225 classify (size t == 0 ) " empty" $
285226 classify (size t > 0 && size t <= 10 ) " small" $
0 commit comments