Yes, I see here that the module Data.Ratio exports thismodule Data.Ratio (
Ratio, Rational, (%), numerator, denominator, approxRational ) wherewhich doesn't include :%. But then I see numerator and denominator which do have :%. But then to use them, this, e.g., won't worknumerator (60 20)It needs the %numerator (60 % 20)So internally, :% is used, but users can never use :%, only %, which sends things through reduce first. I could write my own version of Ratio that didn't hide :<some symbol> and that would be okay. Have I got this right?On Tue, Jul 20, 2021 at 4:37 PM Bob Ippolito <bob@redivi.com> wrote:Yes, the (%) function is a smart constructor for Data.Ratio because the (:%) constructor is not exported. Other examples of this smart constructor technique would be modules like Data.Set or Data.Map.A smart constructor means that the module that defines the type does not export its data constructor(s), making the implementation details opaque, generally because the author wanted to be able to make assumptions about the implementation that are not enforced by the type system. In this case, they wanted all Ratio to be in reduced form. This makes many operations faster or trivial, e.g. implementing Eq only requires comparing the numerators and denominators. More information about the technique is here: https://wiki.haskell.org/Smart_constructors_______________________________________________On Tue, Jul 20, 2021 at 2:17 PM Galaxy Being <borgauf@gmail.com> wrote:... does the last question have to do with a "smart constructor" by chance? If so, how?On Tue, Jul 20, 2021 at 3:42 PM Galaxy Being <borgauf@gmail.com> wrote:I'm investigating rational numbers with Haskell. This is the source I've founddata 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 beendata Ratio a = :% !a !a deriving (Eq)correct? But then what confuses me is in reduce, whyreduce 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?----_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
--_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners