11{-# LANGUAGE CPP #-}
2+ {-# LANGUAGE TypeOperators #-}
3+ {-# LANGUAGE TypeFamilies #-}
24import qualified Data.IntSet as IntSet
35import Data.List (nub , sort , sortBy )
46import qualified Data.List as List
@@ -192,42 +194,7 @@ test_deleteAt = do
192194 Arbitrary, reasonably balanced trees
193195--------------------------------------------------------------------}
194196
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
197+ instance (Int ~ a ) => Arbitrary (Set a ) where
231198 arbitrary = sized (\ sz0 -> do
232199 sz <- choose (0 , sz0)
233200 middle <- choose (- positionFactor * (sz + 1 ), positionFactor * (sz + 1 ))
@@ -241,45 +208,45 @@ instance IsInt a => Arbitrary (Set a) where
241208 diff <- lift $ choose (1 , gapRange)
242209 let i' = i + diff
243210 put i'
244- pure (fromInt i')
211+ pure i'
245212
246- data TwoSets = TwoSets (Set Int ) (Set Int ) deriving (Show )
213+ -- How much the minimum value of an arbitrary set should vary
214+ positionFactor :: Int
215+ positionFactor = 1
247216
248- data TwoLists a = TwoLists [a ] [a ]
217+ -- How much the gap between consecutive elements in an arbitrary
218+ -- set should vary
219+ gapRange :: Int
220+ gapRange = 5
249221
250- data Options2 = One2 | Two2 | Both2 deriving (Bounded , Enum )
251- instance Arbitrary Options2 where
252- arbitrary = arbitraryBoundedEnum
222+ data TwoSets = TwoSets (Set Int ) (Set Int ) deriving (Show )
253223
254224-- We produce two lists from a simple "universe". This instance
255225-- is intended to give good results when the two lists are then
256226-- combined with each other; if other elements are used with them,
257227-- 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-
264228instance Arbitrary TwoSets where
265229 arbitrary = do
266- TwoLists l r <- arbitrary
230+ (l, r) <- sized $ \ sz0 -> do
231+ sz <- choose (0 , sz0)
232+ let universe = [0 ,3 .. 3 * (sz - 1 )]
233+ divide2Gen universe
267234 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))
235+ where
236+ divide2Gen :: [a ] -> Gen ([ a ], [ a ] )
237+ divide2Gen [] = pure ([] , [] )
238+ divide2Gen (x : xs) = do
239+ mIsFirst <- arbitrary
240+ (ls, rs) <- divide2Gen xs
241+ pure $ case mIsFirst of
242+ Just True -> ( (x : ls), rs)
243+ Just False -> (ls, (x : rs))
244+ Nothing -> ( (x : ls), (x : rs))
278245
279246{- -------------------------------------------------------------------
280247 Valid trees
281248--------------------------------------------------------------------}
282- forValid :: (IsInt a , Testable b ) => (Set a -> b ) -> Property
249+ forValid :: (Int ~ a , Testable b ) => (Set a -> b ) -> Property
283250forValid f = forAll arbitrary $ \ t ->
284251 classify (size t == 0 ) " empty" $
285252 classify (size t > 0 && size t <= 10 ) " small" $
0 commit comments