{-# LANGUAGE MagicHash #-}
module EL.Test.ApproxEq (ApproxEq(eq), compare) where
import Prelude hiding (compare)
import qualified Data.Text as Text
import qualified GHC.Prim as Prim
import qualified GHC.Types as Types
compare :: (ApproxEq a, Ord a) => Double -> a -> a -> Ordering
compare eta a b
| eq eta a b = EQ
| a > b = GT
| otherwise = LT
class ApproxEq a where
eq :: Double -> a -> a -> Bool
instance ApproxEq Float where
eq eta x y = abs (x - y) <= d2f eta
instance ApproxEq Double where
eq eta x y = abs (x - y) <= eta
instance ApproxEq Char where eq _ = (==)
instance ApproxEq Int where eq _ = (==)
instance ApproxEq Integer where eq _ = (==)
instance ApproxEq Bool where eq _ = (==)
instance ApproxEq a => ApproxEq [a] where
eq eta = go
where
go [] [] = True
go [] _ = False
go _ [] = False
go (x:xs) (y:ys) = eq eta x y && go xs ys
instance ApproxEq a => ApproxEq (Maybe a) where
eq eta (Just x) (Just y) = eq eta x y
eq _ _ _ = False
instance (ApproxEq a, ApproxEq b) => ApproxEq (Either a b) where
eq eta (Right x) (Right y) = eq eta x y
eq eta (Left x) (Left y) = eq eta x y
eq _ _ _ = False
instance (ApproxEq a, ApproxEq b) => ApproxEq (a, b) where
eq eta (a, b) (a', b') = eq eta a a' && eq eta b b'
instance (ApproxEq a, ApproxEq b, ApproxEq c) => ApproxEq (a, b, c) where
eq eta (a, b, c) (a', b', c') = eq eta a a' && eq eta b b' && eq eta c c'
instance (ApproxEq a, ApproxEq b, ApproxEq c, ApproxEq d) =>
ApproxEq (a, b, c, d) where
eq eta (a, b, c, d) (a', b', c', d') =
eq eta a a' && eq eta b b' && eq eta c c' && eq eta d d'
instance ApproxEq Text.Text where eq _ = (==)
d2f :: Double -> Float
d2f (Types.D# d) = Types.F# (Prim.double2Float# d)