{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-} {-# LANGUAGE NoImplicitPrelude, UndecidableInstances #-} module Algebra.Field.Fraction.Test (arbitraryRational) where import AlgebraicPrelude import Test.QuickCheck (Arbitrary (..), Gen, arbitrarySizedIntegral, suchThat) import Test.SmallCheck.Series (CoSerial (..), Serial (..)) import qualified Test.SmallCheck.Series as SC arbitraryRational :: Gen (Fraction Integer) arbitraryRational :: Gen (Fraction Integer) arbitraryRational = do Integer a <- Gen Integer forall a. Integral a => Gen a arbitrarySizedIntegral Integer b <- Gen Integer forall a. Integral a => Gen a arbitrarySizedIntegral Gen Integer -> (Integer -> Bool) -> Gen Integer forall a. Gen a -> (a -> Bool) -> Gen a `suchThat` \Integer b -> Integer -> Integer -> Integer forall d. GCDDomain d => d -> d -> d gcd Integer a Integer b Integer -> Integer -> Bool forall a. Eq a => a -> a -> Bool == Integer 1 Bool -> Bool -> Bool && Integer b Integer -> Integer -> Bool forall a. Eq a => a -> a -> Bool /= Integer 0 Fraction Integer -> Gen (Fraction Integer) forall (m :: * -> *) a. Monad m => a -> m a return (Fraction Integer -> Gen (Fraction Integer)) -> Fraction Integer -> Gen (Fraction Integer) forall a b. (a -> b) -> a -> b $ Integer a Integer -> Integer -> Fraction Integer forall d. GCDDomain d => d -> d -> Fraction d % Integer -> Integer forall a. Num a => a -> a abs Integer b instance (GCDDomain r, Eq r, Arbitrary r) => Arbitrary (Fraction r) where arbitrary :: Gen (Fraction r) arbitrary = do r a <- Gen r forall a. Arbitrary a => Gen a arbitrary r b <- Gen r forall a. Arbitrary a => Gen a arbitrary Gen r -> (r -> Bool) -> Gen r forall a. Gen a -> (a -> Bool) -> Gen a `suchThat` \r b -> r -> r -> r forall d. GCDDomain d => d -> d -> d gcd r a r b r -> r -> Bool forall a. Eq a => a -> a -> Bool == r forall r. Unital r => r one Bool -> Bool -> Bool && Bool -> Bool not (r -> Bool forall r. DecidableZero r => r -> Bool isZero r b) Fraction r -> Gen (Fraction r) forall (m :: * -> *) a. Monad m => a -> m a return (Fraction r -> Gen (Fraction r)) -> Fraction r -> Gen (Fraction r) forall a b. (a -> b) -> a -> b $ r a r -> r -> Fraction r forall d. GCDDomain d => d -> d -> Fraction d % r b instance {-# OVERLAPPING #-} Arbitrary (Fraction Integer) where arbitrary :: Gen (Fraction Integer) arbitrary = Gen (Fraction Integer) arbitraryRational instance (Euclidean i, Integral i, Serial m i) => Serial m (Fraction i) where series :: Series m (Fraction i) series = (i, Positive i) -> Fraction i forall d. GCDDomain d => (d, Positive d) -> Fraction d pairToRatio ((i, Positive i) -> Fraction i) -> Series m (i, Positive i) -> Series m (Fraction i) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Series m (i, Positive i) forall (m :: * -> *) a. Serial m a => Series m a series where pairToRatio :: (d, Positive d) -> Fraction d pairToRatio (d n, SC.Positive d d) = d n d -> d -> Fraction d forall d. GCDDomain d => d -> d -> Fraction d % d d instance (CoSerial m i) => CoSerial m (Fraction i) where coseries :: Series m b -> Series m (Fraction i -> b) coseries Series m b rs = (((i, i) -> b) -> (Fraction i -> (i, i)) -> Fraction i -> b forall b c a. (b -> c) -> (a -> b) -> a -> c . Fraction i -> (i, i) forall b. Fraction b -> (b, b) ratioToPair) (((i, i) -> b) -> Fraction i -> b) -> Series m ((i, i) -> b) -> Series m (Fraction i -> b) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Series m b -> Series m ((i, i) -> b) forall (m :: * -> *) a b. CoSerial m a => Series m b -> Series m (a -> b) coseries Series m b rs where ratioToPair :: Fraction b -> (b, b) ratioToPair Fraction b r = (Fraction b -> b forall t. Fraction t -> t numerator Fraction b r, Fraction b -> b forall t. Fraction t -> t denominator Fraction b r)