Skip to content

fromRational broken for Ratio a

The Fractional instance for Ratio a in GHC.Real defines

    fromRational (x:%y) =  fromInteger x :% fromInteger y

For fixed-width Integral types, that produces invalid results:

Prelude Data.Ratio> fromRational (1 % 2^32) :: Ratio Int
1 % 0
Prelude Data.Ratio> fromRational (3 % (2^32+9)) :: Ratio Int
3 % 9

Via toRational, these can be ported back to Rational.

Ratio a is generally broken for fixed-width types:

Prelude Data.Ratio> 1 % (minBound :: Int)
(-1) % (-2147483648)

but the particular brokenness of fromRational can be alleviated by reducing:

    fromRational (x:%y) = fromInteger x % fromInteger y

{-# RULES
"fromRational/id"  fromRational = id :: Rational -> Rational
  #-}

I think it's better to throw a divide by zero error than to produce invalid results here.

Trac metadata
Trac field Value
Version 6.12.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information