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