The Ratio type is a fraction. If a is Integer, it is an infinite precision fraction. You can divide it arbitrarily and it will never lose any precision (though it will take more space).

Reduce is designed to create a fraction from two numbers, not solve it. so if you supply 5 and 10, it will return a Ratio 1/2, because 5 is the greatest common denominator.

The % operator appears to take arbitrary numbers but it seems designed to intend to keep the negative sign on the numerator, so as to maintain some invariant in the data.

On Tue, Jul 20, 2021 at 4:43 PM Galaxy Being <borgauf@gmail.com> wrote:
I'm investigating rational numbers with Haskell. This is the source I've found

data Ratio a = !a :% !a deriving (Eq)

reduce ::  (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
reduce _ 0              =  ratioZeroDenominatorError
reduce x y              =  (x `quot` d) :% (y `quot` d)
                           where d = gcd x y
(%) :: (Integral a) => a -> a -> Ratio a
x % y =  reduce (x * signum y) (abs y)

The Ratio data type would seem to be a parameterized type with two parameters of the same type that must be "settled" in that they're not to be lazily dealt with. Then the :% is the data constructor, the : meaning it's a data constructor and not just an operation function. So this could have been

data Ratio a = :% !a !a deriving (Eq)

correct? But then what confuses me is in reduce, why 

reduce x y  =  (x `quot` d) :% (y `quot` d)

and not just %? We have :% defined in the data type and then (%) defined as a function. What is going on here?

--

Lawrence Bottorff
Grand Marais, MN, USA
_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners