{-# OPTIONS_HADDOCK not-home #-}
module Hedgehog.Internal.Shrink (
towards
, towardsFloat
, list
, halves
, removes
, consNub
) where
towards :: Integral a => a -> a -> [a]
towards :: forall a. Integral a => a -> a -> [a]
towards a
destination a
x =
if a
destination forall a. Eq a => a -> a -> Bool
== a
x then
[]
else if a
destination forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& a
x forall a. Eq a => a -> a -> Bool
== a
1 then
[a
0]
else
let
diff :: a
diff =
(a
x forall a. Integral a => a -> a -> a
`quot` a
2) forall a. Num a => a -> a -> a
- (a
destination forall a. Integral a => a -> a -> a
`quot` a
2)
in
a
destination forall a. Eq a => a -> [a] -> [a]
`consNub` forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
x forall a. Num a => a -> a -> a
-) (forall a. Integral a => a -> [a]
halves a
diff)
towardsFloat :: RealFloat a => a -> a -> [a]
towardsFloat :: forall a. RealFloat a => a -> a -> [a]
towardsFloat a
destination a
x =
if a
destination forall a. Eq a => a -> a -> Bool
== a
x then
[]
else
let
diff :: a
diff =
a
x forall a. Num a => a -> a -> a
- a
destination
ok :: a -> Bool
ok a
y =
a
y forall a. Eq a => a -> a -> Bool
/= a
x Bool -> Bool -> Bool
&& Bool -> Bool
not (forall a. RealFloat a => a -> Bool
isNaN a
y) Bool -> Bool -> Bool
&& Bool -> Bool
not (forall a. RealFloat a => a -> Bool
isInfinite a
y)
in
forall a. (a -> Bool) -> [a] -> [a]
takeWhile a -> Bool
ok forall b c a. (b -> c) -> (a -> b) -> a -> c
.
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
x forall a. Num a => a -> a -> a
-) forall a b. (a -> b) -> a -> b
$
forall a. (a -> a) -> a -> [a]
iterate (forall a. Fractional a => a -> a -> a
/ a
2) a
diff
list :: [a] -> [[a]]
list :: forall a. [a] -> [[a]]
list [a]
xs =
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
(\Int
k -> forall a. Int -> [a] -> [[a]]
removes Int
k [a]
xs)
(forall a. Integral a => a -> [a]
halves forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs)
removes :: Int -> [a] -> [[a]]
removes :: forall a. Int -> [a] -> [[a]]
removes Int
k0 [a]
xs0 =
let
loop :: Int -> Int -> [a] -> [[a]]
loop Int
k Int
n [a]
xs =
let
([a]
hd, [a]
tl) =
forall a. Int -> [a] -> ([a], [a])
splitAt Int
k [a]
xs
in
if Int
k forall a. Ord a => a -> a -> Bool
> Int
n then
[]
else if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
tl then
[[]]
else
[a]
tl forall a. a -> [a] -> [a]
: forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([a]
hd forall a. [a] -> [a] -> [a]
++) (Int -> Int -> [a] -> [[a]]
loop Int
k (Int
n forall a. Num a => a -> a -> a
- Int
k) [a]
tl)
in
forall {a}. Int -> Int -> [a] -> [[a]]
loop Int
k0 (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs0) [a]
xs0
halves :: Integral a => a -> [a]
halves :: forall a. Integral a => a -> [a]
halves =
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a. Eq a => a -> a -> Bool
/= a
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a) -> a -> [a]
iterate (forall a. Integral a => a -> a -> a
`quot` a
2)
consNub :: Eq a => a -> [a] -> [a]
consNub :: forall a. Eq a => a -> [a] -> [a]
consNub a
x [a]
ys0 =
case [a]
ys0 of
[] ->
a
x forall a. a -> [a] -> [a]
: []
a
y : [a]
ys ->
if a
x forall a. Eq a => a -> a -> Bool
== a
y then
a
y forall a. a -> [a] -> [a]
: [a]
ys
else
a
x forall a. a -> [a] -> [a]
: a
y forall a. a -> [a] -> [a]
: [a]
ys