semiring-num-1.6.0.0: test/Fraction.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Fraction where
import Data.Semiring
import Test.SmallCheck.Series
import Control.Applicative
newtype Fraction =
Fraction Double
deriving (Show,Num,Fractional,Real,RealFrac,Floating,RealFloat,Semiring)
instance DetectableZero Fraction where isZero = (0==)
instance Eq Fraction where
Fraction x == Fraction y = abs (x - y) < 0.011
instance Ord Fraction where
compare (Fraction x) (Fraction y)
| Fraction x == Fraction y = EQ
| otherwise = compare x y
instance Monad m => Serial m Fraction where
series = fmap Fraction $ generate (\d -> if d >= 0 then pure 0 else empty) <|> rest where
rest = generate $ \d -> take d (1 : go 0 1)
go lower upper = let mid = (lower + upper) / 2 in
mid : interleave (go lower mid) (go mid upper)
interleave (x:xs) (y:ys) = x : y : interleave xs ys
interleave _ _ = undefined