Rational numbers

I’ve just started experimenting with Rescript and couldn’t find support for rational numbers, either built into the language or as a library, but I was able to add a quick-and-dirty LLM-generated Rational.res module and used it like this:

// Demo.res
open Rational

let a = fromString("6/8")
let b = fromString("1/4")
let c = add(a, b)

Console.log("6/8 can be simplified to " + a->toString)
Console.log("a + b = " + c->toString)

It gets transpiled into the following JS:

// Generated by ReScript, PLEASE EDIT WITH CARE

import * as Rational from "./Rational.res.mjs";

let a = Rational.fromString("6/8");

let b = Rational.fromString("1/4");

let c = Rational.add(a, b);

console.log("6/8 can be simplified to " + Rational.toString(a));

console.log("a + b = " + Rational.toString(c));

export {
  a,
  b,
  c,
}
/* a Not a pure module */

Running it outputs the following:

$ node src/Demo.res.mjs
6/8 can be simplified to 3/4
a + b = 1

Overall, I find this quite ergonomic, but of course it would be even nicer to be able to use the regular operators (+, -, * and /). Considering the recent addition of BigInt and unified operators (see Rethinking Operators), would it be feasible to make rational numbers part of the language itself like in Haskell, Julia and Scheme?

There is a hidden feature in ReScript that allows you to overload the basic arithmetic operators.

You can add an Infix module to your Rational library and overload them like this:

// In Rational.res
module Infix = {
  let \"+" = add
  let \"/" = make
}

then use them like this:

open! Rational.Infix

let a = 6 / 8
let b = 1 / 4
let c = a + b

Playground link

Not sure if it makes fully sense though but you get the point.

4 Likes

Thanks, but I wasn’t able to make your hack work. Could you try it on this playground?

A bit of copy-paste seemed to add it in on my end.
Playground

2 Likes

You beat me to it!

However, the whole fromString-conversion can be skipped with infix if we are ok with the n behind each number:

Playground

Edit: Again not sure if it makes sense, because then division has no operator anymore.

1 Like

Thank you so much!

@fham: / will be needed for division of rational numbers, but one can use % to construct rationals.

In both Haskell and purescript-rationals, % is used for this purpose.

3 Likes

That’s true - since ReScript 12 we also have the % operator which you can overload as well.

1 Like