How is Ratio implemented in Haskell?
haskell
Solution
`Ratio` is actually implemented in `GHC.Real` (on GHC, obviously), and is defined as
data Ratio a = !a :% !a deriving (Eq)
The bangs are just there for strictness. As you can see, the function `%` is not a data constructor, but `:%` is. Since you aren't supposed to construct a `Ratio` directly, you use the `%` function, which calls reduce.
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 rule is that if an operator starts with a colon `:`, then it is a constructor, otherwise it is just a normal operator. In fact, this is part of the Haskell standard, all type operators must have a colon as their first character.
Problem
This is something I have been confused about for a while and I am not sure how I can learn more about it. Let's say I have the following program: ``` main :: IO () main = do x <- liftM read getLine y <- liftM read getLine print (x % y) ``` If I run this with the input `6` and `2`, it will print `3 % 1`. At what point does the simplification happen (namely the division by the gcd)? Is it implemented in `show`? If so, then is the underlying representation of the rational still `6 % 2`? If not, then does `(%)` do the simplification? I was under the impression that `(%)` is a data constructor, so how would a data constructor do anything more than "construct"? More importantly, how would I actually go about doing similar things with my own data constructors? I appreciate any help on the topic.