123
115
do k <- choose (0,n)
124
116
sequence [ arbitrary | _ <- [1..k] ]
126
shrink xs = removeChunks xs
118
shrink xs = shrinkList shrink xs
120
shrinkList :: (a -> [a]) -> [a] -> [[a]]
121
shrinkList shr xs = removeChunks xs ++ shrinkOne xs
123
removeChunks xs = rem (length xs) xs
129
removeChunks xs = rem (length xs) xs
129
: ( [ xs1' ++ xs2 | xs1' <- rem n1 xs1, not (null xs1') ]
130
`ilv` [ xs1 ++ xs2' | xs2' <- rem n2 xs2, not (null xs2') ]
135
: ( [ xs1' ++ xs2 | xs1' <- rem n1 xs1, not (null xs1') ]
136
`ilv` [ xs1 ++ xs2' | xs2' <- rem n2 xs2, not (null xs2') ]
146
(x:xs) `ilv` (y:ys) = x : y : (xs `ilv` ys)
149
shrinkOne (x:xs) = [ x':xs | x' <- shrink x ]
150
++ [ x:xs' | xs' <- shrinkOne xs ]
140
(x:xs) `ilv` (y:ys) = x : y : (xs `ilv` ys)
143
shrinkOne (x:xs) = [ x':xs | x' <- shr x ]
144
++ [ x:xs' | xs' <- shrinkOne xs ]
153
147
-- "standard" definition for lists:
435
443
orderedList = sort `fmap` arbitrary
437
445
--------------------------------------------------------------------------
441
prop_TakeDropWhile (Blind p) (xs :: [A]) = -- because functions cannot be shown
442
takeWhile p xs ++ dropWhile p xs == xs
444
prop_TakeDrop (NonNegative n) (xs :: [A]) = -- (BTW, also works for negative n)
445
take n xs ++ drop n xs == xs
447
prop_Cycle (NonNegative n) (NonEmpty (xs :: [A])) = -- cycle does not work for empty lists
448
take n (cycle xs) == take n (xs ++ cycle xs)
450
prop_Sort (Ordered (xs :: [OrdA])) = -- instead of "forAll orderedList"
454
newtype Blind a = Blind a
455
deriving ( Eq, Ord, Num, Integral, Real, Enum )
457
instance Show (Blind a) where
460
instance Arbitrary a => Arbitrary (Blind a) where
461
arbitrary = Blind `fmap` arbitrary
463
shrink (Blind x) = [ Blind x' | x' <- shrink x ]
465
newtype Fixed a = Fixed a
466
deriving ( Eq, Ord, Num, Integral, Real, Enum, Show, Read )
468
instance Arbitrary a => Arbitrary (Fixed a) where
469
arbitrary = Fixed `fmap` arbitrary
471
-- no shrink function
473
newtype OrderedList a = Ordered [a]
474
deriving ( Eq, Ord, Show, Read )
476
instance (Ord a, Arbitrary a) => Arbitrary (OrderedList a) where
477
arbitrary = Ordered `fmap` orderedList
479
shrink (Ordered xs) =
485
newtype NonEmptyList a = NonEmpty [a]
486
deriving ( Eq, Ord, Show, Read )
488
instance Arbitrary a => Arbitrary (NonEmptyList a) where
489
arbitrary = NonEmpty `fmap` (arbitrary `suchThat` (not . null))
491
shrink (NonEmpty xs) =
497
newtype Positive a = Positive a
498
deriving ( Eq, Ord, Num, Integral, Real, Enum, Show, Read )
500
instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
502
(Positive . abs) `fmap` (arbitrary `suchThat` (/= 0))
504
shrink (Positive x) =
510
newtype NonZero a = NonZero a
511
deriving ( Eq, Ord, Num, Integral, Real, Enum, Show, Read )
513
instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonZero a) where
514
arbitrary = fmap NonZero $ arbitrary `suchThat` (/= 0)
516
shrink (NonZero x) = [ NonZero x' | x' <- shrink x, x' /= 0 ]
518
newtype NonNegative a = NonNegative a
519
deriving ( Eq, Ord, Num, Integral, Real, Enum, Show, Read )
521
instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonNegative a) where
524
-- why is this distrbution like this?
525
[ (5, (NonNegative . abs) `fmap` arbitrary)
529
shrink (NonNegative x) =
538
instance Show a => Show (Smart a) where
539
showsPrec n (Smart _ x) = showsPrec n x
541
instance Arbitrary a => Arbitrary (Smart a) where
546
shrink (Smart i x) = take i' ys `ilv` drop i' ys
548
ys = [ Smart i y | (i,y) <- [0..] `zip` shrink x ]
553
(a:as) `ilv` (b:bs) = a : b : (as `ilv` bs)
556
shrink (Smart i x) = part0 ++ part2 ++ part1
558
ys = [ Smart i y | (i,y) <- [0..] `zip` shrink x ]
563
part1 = take (i'-k) (drop k ys)
567
-- drop a (drop b xs) == drop (a+b) xs | a,b >= 0
568
-- take a (take b xs) == take (a `min` b) xs
569
-- take a xs ++ drop a xs == xs
571
-- take k ys ++ take (i'-k) (drop k ys) ++ drop i' ys
572
-- == take k ys ++ take (i'-k) (drop k ys) ++ drop (i'-k) (drop k ys)
573
-- == take k ys ++ take (i'-k) (drop k ys) ++ drop (i'-k) (drop k ys)
574
-- == take k ys ++ drop k ys
580
class ShrinkState s a where
582
shrinkState :: a -> s -> [(a,s)]
584
instance Show a => Show (Shrinking s a) where
585
showsPrec n (Shrinking _ x) = showsPrec n x
587
instance (Arbitrary a, ShrinkState s a) => Arbitrary (Shrinking s a) where
590
return (Shrinking (shrinkInit x) x)
592
shrink (Shrinking s x) =
594
| (x',s') <- shrinkState x s
597
--------------------------------------------------------------------------