I am writing a small script with some combinatorics utilities. When I need a numeric literal like 0
or 1
in a different type, I use _0
and _1
, but this solution is less than ideal. Is it possible to use Camlp4 to reinterpret numeric literals within a given context or add a new type of numeric literal with a dedicated suffix?
open Num
let zero = num_of_int 0
let one = num_of_int 1
let _0 = zero
let _1 = one
(* some useful infix operators *)
let ( + ) = ( +/ )
let ( - ) = ( -/ )
let ( * ) = ( */ )
let ( < ) = ( </ )
let ( > ) = ( >/ )
let ( = ) = ( =/ )
let ( / ) numer denom =
if mod_num numer denom = _0
then div_num numer denom
else invalid_arg "division is not a total function"
(* factorial, naive *)
let rec fact n =
if n < _0
then invalid_arg "negative factorial"
else if n = _0
then _1
else
n * fact (n - _1)
(* naive algorithm *)
let choose n k = (fact n / fact k) / fact (n - k)
In short, no. Camlp4 is preprocessor of untyped parse tree. It cannot do such type sensitive thing.
If you would want (and I bet you will not), you can run type checking against the untyped parse trees in Camlp4 and infer the types of your special numerals, then replace them by corresponding values. It is theoretically possible but none has ever tried it, since P4's parse tree is completely different from the one of OCaml.
PPX preprocessor, which is meant to replace Campl4, has some hope, since it handles the same untyped parse tree as OCaml and therefore it is easy to apply OCaml type checker. TyPPX (https://bitbucket.org/camlspotter/typpx) is such a framework to provide APIs for type dependent preprocessing.