module MagicHaskeller.NearEq where
import MagicHaskeller.FastRatio
infix 4 ~=
class NearEq a where
(~=) :: a -> a -> Bool
instance NearEq Double where
Double
a ~= :: Double -> Double -> Bool
~= Double
b = Bool
naBool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
==Bool
nb Bool -> Bool -> Bool
&& Bool
ia Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
b Bool -> Bool -> Bool
&& Double -> Double
forall a. Num a => a -> a
signum Double
a Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double -> Double
forall a. Num a => a -> a
signum Double
b Bool -> Bool -> Bool
&& (Bool
na Bool -> Bool -> Bool
|| Bool
ia Bool -> Bool -> Bool
|| Double -> Double
forall a. Num a => a -> a
abs (Double
aDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
b) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= (Int -> Double -> Double
forall a. RealFloat a => Int -> a -> a
scaleFloat (-Int
24) (Double -> Double) -> Double -> Double
forall a b. (a -> b) -> a -> b
$ Double -> Double
forall a. Num a => a -> a
abs Double
a))
where na :: Bool
na = Double -> Bool
forall a. RealFloat a => a -> Bool
isNaN Double
a
nb :: Bool
nb = Double -> Bool
forall a. RealFloat a => a -> Bool
isNaN Double
b
ia :: Bool
ia = Double -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Double
a
instance NearEq Float where
Float
a ~= :: Float -> Float -> Bool
~= Float
b = Bool
naBool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
==Bool
nb Bool -> Bool -> Bool
&& Bool
ia Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
b Bool -> Bool -> Bool
&& Float -> Float
forall a. Num a => a -> a
signum Float
a Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float -> Float
forall a. Num a => a -> a
signum Float
b Bool -> Bool -> Bool
&& (Bool
na Bool -> Bool -> Bool
|| Bool
ia Bool -> Bool -> Bool
|| Float -> Float
forall a. Num a => a -> a
abs (Float
aFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
b) Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
<= (Int -> Float -> Float
forall a. RealFloat a => Int -> a -> a
scaleFloat (-Int
12) (Float -> Float) -> Float -> Float
forall a b. (a -> b) -> a -> b
$ Float -> Float
forall a. Num a => a -> a
abs Float
a))
where na :: Bool
na = Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
a
nb :: Bool
nb = Float -> Bool
forall a. RealFloat a => a -> Bool
isNaN Float
b
ia :: Bool
ia = Float -> Bool
forall a. RealFloat a => a -> Bool
isInfinite Float
a
instance NearEq () where
()
x ~= :: () -> () -> Bool
~= ()
y = ()
x () -> () -> Bool
forall a. Eq a => a -> a -> Bool
== ()
y
instance NearEq Bool where
Bool
x ~= :: Bool -> Bool -> Bool
~= Bool
y = Bool
x Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
y
instance NearEq Ordering where
Ordering
x ~= :: Ordering -> Ordering -> Bool
~= Ordering
y = Ordering
x Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
y
instance NearEq Char where
Char
x ~= :: Char -> Char -> Bool
~= Char
y = Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
y
instance NearEq Int where
Int
x ~= :: Int -> Int -> Bool
~= Int
y = Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y
instance NearEq Integer where
Integer
x ~= :: Integer -> Integer -> Bool
~= Integer
y = Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
y
instance (NearEq i, Integral i) => NearEq (Ratio i) where
Ratio i
x ~= :: Ratio i -> Ratio i -> Bool
~= Ratio i
y = Ratio i -> i
forall a. Integral a => Ratio a -> a
numerator Ratio i
x i -> i -> Bool
forall a. NearEq a => a -> a -> Bool
~= Ratio i -> i
forall a. Integral a => Ratio a -> a
numerator Ratio i
y Bool -> Bool -> Bool
&& Ratio i -> i
forall a. Integral a => Ratio a -> a
denominator Ratio i
x i -> i -> Bool
forall a. NearEq a => a -> a -> Bool
~= Ratio i -> i
forall a. Integral a => Ratio a -> a
denominator Ratio i
y
instance NearEq a => NearEq [a] where
[] ~= :: [a] -> [a] -> Bool
~= [] = Bool
True
a
x:[a]
xs ~= a
y:[a]
ys = a
x a -> a -> Bool
forall a. NearEq a => a -> a -> Bool
~= a
y Bool -> Bool -> Bool
&& [a]
xs [a] -> [a] -> Bool
forall a. NearEq a => a -> a -> Bool
~= [a]
ys
[a]
_ ~= [a]
_ = Bool
False
instance NearEq a => NearEq (Maybe a) where
Maybe a
Nothing ~= :: Maybe a -> Maybe a -> Bool
~= Maybe a
Nothing = Bool
True
Just a
x ~= Just a
y = a
x a -> a -> Bool
forall a. NearEq a => a -> a -> Bool
~= a
y
Maybe a
_ ~= Maybe a
_ = Bool
False
instance (NearEq a, NearEq b) => NearEq (Either a b) where
Left a
x ~= :: Either a b -> Either a b -> Bool
~= Left a
y = a
x a -> a -> Bool
forall a. NearEq a => a -> a -> Bool
~= a
y
Right b
x ~= Right b
y = b
x b -> b -> Bool
forall a. NearEq a => a -> a -> Bool
~= b
y
Either a b
_ ~= Either a b
_ = Bool
False
instance (NearEq a, NearEq b) => NearEq (a,b) where
(a
x1,b
x2) ~= :: (a, b) -> (a, b) -> Bool
~= (a
y1,b
y2) = a
x1 a -> a -> Bool
forall a. NearEq a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. NearEq a => a -> a -> Bool
~= b
y2
instance (NearEq a, NearEq b, NearEq c) => NearEq (a,b,c) where
(a
x1,b
x2,c
x3) ~= :: (a, b, c) -> (a, b, c) -> Bool
~= (a
y1,b
y2,c
y3) = a
x1 a -> a -> Bool
forall a. NearEq a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. NearEq a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. NearEq a => a -> a -> Bool
~= c
y3