<div dir="ltr"><div>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).</div><div><br></div><div>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.</div><div><br></div><div>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.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 20, 2021 at 4:43 PM Galaxy Being <<a href="mailto:borgauf@gmail.com">borgauf@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">I'm investigating rational numbers with Haskell. This is the source I've found<div><br></div><div><font face="monospace">data Ratio a = !a :% !a deriving (Eq)<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">reduce ::  (Integral a) => a -> a -> Ratio a<br>{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}<br>reduce _ 0              =  ratioZeroDenominatorError<br>reduce x y              =  (x `quot` d) :% (y `quot` d)<br>                           where d = gcd x y<br>(%) :: (Integral a) => a -> a -> Ratio a<br>x % y =  reduce (x * signum y) (abs y)</font></div><div><font face="monospace"><br></font></div><div><font face="arial, sans-serif">The </font><font face="monospace">Ratio</font><font face="arial, sans-serif"> 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 </font><font face="monospace">:% </font><font face="arial, sans-serif">is the data constructor, the </font><font face="monospace">:</font><font face="arial, sans-serif"> meaning it's a data constructor and not just an operation function. So this could have been</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="monospace">data Ratio a = :% !a !a deriving (Eq)</font></div><div><br></div><div>correct? But then what confuses me is in reduce, why <br clear="all"><div><br></div><div><font face="monospace">reduce x y  =  (x `quot` d) :% (y `quot` d)</font><br></div><div><br></div><div>and not just <font face="monospace">%</font>? We have<font face="monospace"> :%</font> defined in the data type and then <font face="monospace">(%)</font> defined as a function. What is going on here?</div><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div>⨽<br></div>Lawrence Bottorff<div>Grand Marais, MN, USA</div><div><a href="mailto:borgauf@gmail.com" target="_blank">borgauf@gmail.com</a></div></div></div></div></div>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>