Jerzy Karczmarczuk wrote:
> [snip]
>> I remind you that there is still an uncorrected bug in the domain of
>> rationals (at least in Hugs, but I believe that also elsewhere, since
>> this is a plain Haskell bug in the Prelude).
>>
>> succ (3%2)
>>
>> gives 2%1.
On Mon, Jul 10, 2000 at 11:34:18AM +0200, George Russell wrote:
> Yes, this is also loony. succ should either give the least greater value
> (in which case it can't be defined for rationals but can and be useful for
> floats) or the value+1.
The rationals may be enumerated according to the construction given by
Cantor, or by various other means. Cantor's construction was to arrange
pairs of natural numbers (i,j) in a big 2-D array, strike out the entries
with gcd(i,j) /= 1, and then traverse the diagonals of the array. Some
Haskell code which does this is the following:
zipDiag :: [a] -> [b] -> [(a,b)]
zipDiag xs ys = concat $ zipWith (map . (,)) xs (tail $ inits ys)
diag :: [a] -> [(a,a)]
diag xs = zipDiag xs xs
diagZ :: [(Integer, Integer)]
diagZ = [mn | mn <- diag [1..], (uncurry gcd) mn == 1]
nthRational :: Integral a => a -> Ratio Integer
nthRational n = uncurry (%) $ diagZ `genericIndex` n
rationals = map (uncurry (%)) diagZ
I suppose this only handles the positive rationals. It shouldn't be
terribly hard to (a) stick zero in there somewhere and (b) interleave
the positive and negative rationals. On the other hand, there isn't a
terribly obvious way to get the next rational in this enumeration. If
anybody knows of a better way, do tell. There is also the fact that
this enumeration (and probably most others as well) of the rationals
isn't terribly useful in programming contexts to worry about, but I
suppose the point is made.
Cheers,
Bill