Working with rationals

I have some work at the moment that might need to manipulate floating point numbers. However, I realised that it’s probably sufficient to just work with rationals, which are much simpler. I can represent a rational as Ratio = { numerator : Natural, denominator : Natural }. However, this is pretty horrible for users to construct. For example, I want to write 0.001, but I have to write { numerator = 1, denominator = 1000 } - this example took me many seconds to write to work out exactly how many zeros I needed!

We’ve got the normal escape hatch of postulating Text/parse-Ratio : Text -> Ratio, but can anyone think of anything else?

Something like

e 12 (pos 2)
-> {numerator = 1200, denominator = 1}  == 1200

e 12 (neg 2)
-> {numerator 12, denominator 100} == 0.12

?

1 Like

Oh that’s an interesting idea! Yes, that may well work, if we had Integer -> < Negative : Natural | Zero | Positive : Natural > it would be even tidier. Then it could just be e 123 -5.

Alright, I threw together

let e =
        λ(coefficient : Natural)
      → λ(exponent : < Positive : Natural | Negative : Natural >)
      → merge
        { Positive =
              λ(n : Natural)
            → { numerator =
                  Natural/fold n Natural (λ(i : Natural) → i * 10) coefficient
              , denominator =
                  1
              }
        , Negative =
              λ(n : Natural)
            → { numerator =
                  coefficient
              , denominator =
                  Natural/fold n Natural (λ(i : Natural) → i * 10) 1
              }
        }
        exponent

in  e

which does work. Whether or not it’s still ergonomic enough to write stuff in scientific notation remains to be seen, but it’s a start.

1 Like