{-# OPTIONS_HADDOCK not-home #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Hedgehog.Internal.Range (
Size(..)
, Range(..)
, origin
, bounds
, lowerBound
, upperBound
, singleton
, constant
, constantFrom
, constantBounded
, linear
, linearFrom
, linearFrac
, linearFracFrom
, linearBounded
, exponential
, exponentialFrom
, exponentialBounded
, exponentialFloat
, exponentialFloatFrom
, clamp
, scaleLinear
, scaleLinearFrac
, scaleExponential
, scaleExponentialFloat
) where
import Data.Bifunctor (bimap)
import Prelude hiding (minimum, maximum)
newtype Size =
Size {
Size -> Int
unSize :: Int
} deriving (Size -> Size -> Bool
(Size -> Size -> Bool) -> (Size -> Size -> Bool) -> Eq Size
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Size -> Size -> Bool
$c/= :: Size -> Size -> Bool
== :: Size -> Size -> Bool
$c== :: Size -> Size -> Bool
Eq, Eq Size
Eq Size
-> (Size -> Size -> Ordering)
-> (Size -> Size -> Bool)
-> (Size -> Size -> Bool)
-> (Size -> Size -> Bool)
-> (Size -> Size -> Bool)
-> (Size -> Size -> Size)
-> (Size -> Size -> Size)
-> Ord Size
Size -> Size -> Bool
Size -> Size -> Ordering
Size -> Size -> Size
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Size -> Size -> Size
$cmin :: Size -> Size -> Size
max :: Size -> Size -> Size
$cmax :: Size -> Size -> Size
>= :: Size -> Size -> Bool
$c>= :: Size -> Size -> Bool
> :: Size -> Size -> Bool
$c> :: Size -> Size -> Bool
<= :: Size -> Size -> Bool
$c<= :: Size -> Size -> Bool
< :: Size -> Size -> Bool
$c< :: Size -> Size -> Bool
compare :: Size -> Size -> Ordering
$ccompare :: Size -> Size -> Ordering
$cp1Ord :: Eq Size
Ord, Integer -> Size
Size -> Size
Size -> Size -> Size
(Size -> Size -> Size)
-> (Size -> Size -> Size)
-> (Size -> Size -> Size)
-> (Size -> Size)
-> (Size -> Size)
-> (Size -> Size)
-> (Integer -> Size)
-> Num Size
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Size
$cfromInteger :: Integer -> Size
signum :: Size -> Size
$csignum :: Size -> Size
abs :: Size -> Size
$cabs :: Size -> Size
negate :: Size -> Size
$cnegate :: Size -> Size
* :: Size -> Size -> Size
$c* :: Size -> Size -> Size
- :: Size -> Size -> Size
$c- :: Size -> Size -> Size
+ :: Size -> Size -> Size
$c+ :: Size -> Size -> Size
Num, Num Size
Ord Size
Num Size -> Ord Size -> (Size -> Rational) -> Real Size
Size -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: Size -> Rational
$ctoRational :: Size -> Rational
$cp2Real :: Ord Size
$cp1Real :: Num Size
Real, Int -> Size
Size -> Int
Size -> [Size]
Size -> Size
Size -> Size -> [Size]
Size -> Size -> Size -> [Size]
(Size -> Size)
-> (Size -> Size)
-> (Int -> Size)
-> (Size -> Int)
-> (Size -> [Size])
-> (Size -> Size -> [Size])
-> (Size -> Size -> [Size])
-> (Size -> Size -> Size -> [Size])
-> Enum Size
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Size -> Size -> Size -> [Size]
$cenumFromThenTo :: Size -> Size -> Size -> [Size]
enumFromTo :: Size -> Size -> [Size]
$cenumFromTo :: Size -> Size -> [Size]
enumFromThen :: Size -> Size -> [Size]
$cenumFromThen :: Size -> Size -> [Size]
enumFrom :: Size -> [Size]
$cenumFrom :: Size -> [Size]
fromEnum :: Size -> Int
$cfromEnum :: Size -> Int
toEnum :: Int -> Size
$ctoEnum :: Int -> Size
pred :: Size -> Size
$cpred :: Size -> Size
succ :: Size -> Size
$csucc :: Size -> Size
Enum, Enum Size
Real Size
Real Size
-> Enum Size
-> (Size -> Size -> Size)
-> (Size -> Size -> Size)
-> (Size -> Size -> Size)
-> (Size -> Size -> Size)
-> (Size -> Size -> (Size, Size))
-> (Size -> Size -> (Size, Size))
-> (Size -> Integer)
-> Integral Size
Size -> Integer
Size -> Size -> (Size, Size)
Size -> Size -> Size
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: Size -> Integer
$ctoInteger :: Size -> Integer
divMod :: Size -> Size -> (Size, Size)
$cdivMod :: Size -> Size -> (Size, Size)
quotRem :: Size -> Size -> (Size, Size)
$cquotRem :: Size -> Size -> (Size, Size)
mod :: Size -> Size -> Size
$cmod :: Size -> Size -> Size
div :: Size -> Size -> Size
$cdiv :: Size -> Size -> Size
rem :: Size -> Size -> Size
$crem :: Size -> Size -> Size
quot :: Size -> Size -> Size
$cquot :: Size -> Size -> Size
$cp2Integral :: Enum Size
$cp1Integral :: Real Size
Integral)
instance Show Size where
showsPrec :: Int -> Size -> ShowS
showsPrec Int
p (Size Int
x) =
Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
String -> ShowS
showString String
"Size " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Int -> Int -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int
x
instance Read Size where
readsPrec :: Int -> ReadS Size
readsPrec Int
p =
Bool -> ReadS Size -> ReadS Size
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ReadS Size -> ReadS Size) -> ReadS Size -> ReadS Size
forall a b. (a -> b) -> a -> b
$ \String
r0 -> do
(String
"Size", String
r1) <- ReadS String
lex String
r0
(Int
s, String
r2) <- Int -> ReadS Int
forall a. Read a => Int -> ReadS a
readsPrec Int
11 String
r1
(Size, String) -> [(Size, String)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> Size
Size Int
s, String
r2)
data Range a =
Range !a (Size -> (a, a))
instance Functor Range where
fmap :: (a -> b) -> Range a -> Range b
fmap a -> b
f (Range a
z Size -> (a, a)
g) =
b -> (Size -> (b, b)) -> Range b
forall a. a -> (Size -> (a, a)) -> Range a
Range (a -> b
f a
z) ((Size -> (b, b)) -> Range b) -> (Size -> (b, b)) -> Range b
forall a b. (a -> b) -> a -> b
$ \Size
sz ->
(a -> b) -> (a -> b) -> (a, a) -> (b, b)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f a -> b
f (Size -> (a, a)
g Size
sz)
origin :: Range a -> a
origin :: Range a -> a
origin (Range a
z Size -> (a, a)
_) =
a
z
bounds :: Size -> Range a -> (a, a)
bounds :: Size -> Range a -> (a, a)
bounds Size
sz (Range a
_ Size -> (a, a)
f) =
Size -> (a, a)
f Size
sz
lowerBound :: Ord a => Size -> Range a -> a
lowerBound :: Size -> Range a -> a
lowerBound Size
sz Range a
range =
let
(a
x, a
y) =
Size -> Range a -> (a, a)
forall a. Size -> Range a -> (a, a)
bounds Size
sz Range a
range
in
a -> a -> a
forall a. Ord a => a -> a -> a
min a
x a
y
upperBound :: Ord a => Size -> Range a -> a
upperBound :: Size -> Range a -> a
upperBound Size
sz Range a
range =
let
(a
x, a
y) =
Size -> Range a -> (a, a)
forall a. Size -> Range a -> (a, a)
bounds Size
sz Range a
range
in
a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
y
singleton :: a -> Range a
singleton :: a -> Range a
singleton a
x =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
x ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
_ -> (a
x, a
x)
constant :: a -> a -> Range a
constant :: a -> a -> Range a
constant a
x a
y =
a -> a -> a -> Range a
forall a. a -> a -> a -> Range a
constantFrom a
x a
x a
y
constantFrom ::
a
-> a
-> a
-> Range a
constantFrom :: a -> a -> a -> Range a
constantFrom a
z a
x a
y =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
z ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
_ -> (a
x, a
y)
constantBounded :: (Bounded a, Num a) => Range a
constantBounded :: Range a
constantBounded =
a -> a -> a -> Range a
forall a. a -> a -> a -> Range a
constantFrom a
0 a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound
linear :: Integral a => a -> a -> Range a
linear :: a -> a -> Range a
linear a
x a
y =
a -> a -> a -> Range a
forall a. Integral a => a -> a -> a -> Range a
linearFrom a
x a
x a
y
linearFrom :: Integral a
=> a
-> a
-> a
-> Range a
linearFrom :: a -> a -> a -> Range a
linearFrom a
z a
x a
y =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
z ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
sz ->
let
x_sized :: a
x_sized =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Integral a => Size -> a -> a -> a
scaleLinear Size
sz a
z a
x
y_sized :: a
y_sized =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Integral a => Size -> a -> a -> a
scaleLinear Size
sz a
z a
y
in
(a
x_sized, a
y_sized)
linearBounded :: (Bounded a, Integral a) => Range a
linearBounded :: Range a
linearBounded =
a -> a -> a -> Range a
forall a. Integral a => a -> a -> a -> Range a
linearFrom a
0 a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound
linearFrac :: (Fractional a, Ord a) => a -> a -> Range a
linearFrac :: a -> a -> Range a
linearFrac a
x a
y =
a -> a -> a -> Range a
forall a. (Fractional a, Ord a) => a -> a -> a -> Range a
linearFracFrom a
x a
x a
y
linearFracFrom :: (Fractional a, Ord a) => a -> a -> a -> Range a
linearFracFrom :: a -> a -> a -> Range a
linearFracFrom a
z a
x a
y =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
z ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
sz ->
let
x_sized :: a
x_sized =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Fractional a => Size -> a -> a -> a
scaleLinearFrac Size
sz a
z a
x
y_sized :: a
y_sized =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Fractional a => Size -> a -> a -> a
scaleLinearFrac Size
sz a
z a
y
in
(a
x_sized, a
y_sized)
clamp :: Ord a => a -> a -> a -> a
clamp :: a -> a -> a -> a
clamp a
x a
y a
n =
if a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
y then
a -> a -> a
forall a. Ord a => a -> a -> a
min a
x (a -> a -> a
forall a. Ord a => a -> a -> a
max a
y a
n)
else
a -> a -> a
forall a. Ord a => a -> a -> a
min a
y (a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
n)
scaleLinear :: Integral a => Size -> a -> a -> a
scaleLinear :: Size -> a -> a -> a
scaleLinear Size
sz0 a
z0 a
n0 =
let
sz :: Size
sz =
Size -> Size -> Size
forall a. Ord a => a -> a -> a
max Size
0 (Size -> Size -> Size
forall a. Ord a => a -> a -> a
min Size
99 Size
sz0)
z :: Integer
z =
a -> Integer
forall a. Integral a => a -> Integer
toInteger a
z0
n :: Integer
n =
a -> Integer
forall a. Integral a => a -> Integer
toInteger a
n0
rng :: Integer
rng =
Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer
forall a. Num a => a -> a
signum (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
z)
diff :: Integer
diff =
(Integer
rng Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Size -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Size
sz) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`quot` Integer
100
in
Integer -> a
forall a. Num a => Integer -> a
fromInteger (Integer -> a) -> Integer -> a
forall a b. (a -> b) -> a -> b
$ Integer
z Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
diff
scaleLinearFrac :: Fractional a => Size -> a -> a -> a
scaleLinearFrac :: Size -> a -> a -> a
scaleLinearFrac Size
sz0 a
z a
n =
let
sz :: Size
sz =
Size -> Size -> Size
forall a. Ord a => a -> a -> a
max Size
0 (Size -> Size -> Size
forall a. Ord a => a -> a -> a
min Size
99 Size
sz0)
diff :: a
diff =
(a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
z) a -> a -> a
forall a. Num a => a -> a -> a
* (Size -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Size
sz a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
99)
in
a
z a -> a -> a
forall a. Num a => a -> a -> a
+ a
diff
exponential :: Integral a => a -> a -> Range a
exponential :: a -> a -> Range a
exponential a
x a
y =
a -> a -> a -> Range a
forall a. Integral a => a -> a -> a -> Range a
exponentialFrom a
x a
x a
y
exponentialFrom :: Integral a
=> a
-> a
-> a
-> Range a
exponentialFrom :: a -> a -> a -> Range a
exponentialFrom a
z a
x a
y =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
z ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
sz ->
let
sized_x :: a
sized_x =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Integral a => Size -> a -> a -> a
scaleExponential Size
sz a
z a
x
sized_y :: a
sized_y =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Integral a => Size -> a -> a -> a
scaleExponential Size
sz a
z a
y
in
(a
sized_x, a
sized_y)
exponentialBounded :: (Bounded a, Integral a) => Range a
exponentialBounded :: Range a
exponentialBounded =
a -> a -> a -> Range a
forall a. Integral a => a -> a -> a -> Range a
exponentialFrom a
0 a
forall a. Bounded a => a
minBound a
forall a. Bounded a => a
maxBound
exponentialFloat :: (Floating a, Ord a) => a -> a -> Range a
exponentialFloat :: a -> a -> Range a
exponentialFloat a
x a
y =
a -> a -> a -> Range a
forall a. (Floating a, Ord a) => a -> a -> a -> Range a
exponentialFloatFrom a
x a
x a
y
exponentialFloatFrom :: (Floating a, Ord a) => a -> a -> a -> Range a
exponentialFloatFrom :: a -> a -> a -> Range a
exponentialFloatFrom a
z a
x a
y =
a -> (Size -> (a, a)) -> Range a
forall a. a -> (Size -> (a, a)) -> Range a
Range a
z ((Size -> (a, a)) -> Range a) -> (Size -> (a, a)) -> Range a
forall a b. (a -> b) -> a -> b
$ \Size
sz ->
let
sized_x :: a
sized_x =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Floating a => Size -> a -> a -> a
scaleExponentialFloat Size
sz a
z a
x
sized_y :: a
sized_y =
a -> a -> a -> a
forall a. Ord a => a -> a -> a -> a
clamp a
x a
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Size -> a -> a -> a
forall a. Floating a => Size -> a -> a -> a
scaleExponentialFloat Size
sz a
z a
y
in
(a
sized_x, a
sized_y)
scaleExponential :: Integral a => Size -> a -> a -> a
scaleExponential :: Size -> a -> a -> a
scaleExponential Size
sz a
z0 a
n0 =
let
z :: Double
z =
a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
z0
n :: Double
n =
a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n0
in
Double -> a
forall a b. (RealFrac a, Integral b) => a -> b
round (Size -> Double -> Double -> Double
forall a. Floating a => Size -> a -> a -> a
scaleExponentialFloat Size
sz Double
z Double
n :: Double)
scaleExponentialFloat :: Floating a => Size -> a -> a -> a
scaleExponentialFloat :: Size -> a -> a -> a
scaleExponentialFloat Size
sz0 a
z a
n =
let
sz :: Size
sz =
Size -> Size -> Size -> Size
forall a. Ord a => a -> a -> a -> a
clamp Size
0 Size
99 Size
sz0
diff :: a
diff =
(((a -> a
forall a. Num a => a -> a
abs (a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
z) a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) a -> a -> a
forall a. Floating a => a -> a -> a
** (Size -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac Size
sz a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
99)) a -> a -> a
forall a. Num a => a -> a -> a
- a
1) a -> a -> a
forall a. Num a => a -> a -> a
* a -> a
forall a. Num a => a -> a
signum (a
n a -> a -> a
forall a. Num a => a -> a -> a
- a
z)
in
a
z a -> a -> a
forall a. Num a => a -> a -> a
+ a
diff