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.

Original source