'Unboxed typed int in OCaml

I would like to represent two types of integers in my OCaml program and have the compiler emit an error when one type is used in place of the other. My program converts between the two integer types, and a large fraction of the run time is spent operating on such values. If possible, I would like arithmetic operations to run on unboxed values. I implemented a module that defines such a type, and that implements the +, -, /, * operators. But my understanding is that the operations run on boxed values. Is there a way of getting the same behavior with unboxed values?

module SkipInts = struct
  type t = Int of int | SkipInt of int
end


Solution 1:[1]

You could use private type abbreviations to create a distinct type for SkipInt represented as an int:

module SkipInt : sig 
  type t = private int
  
  val of_int : int -> t
  val to_int : t -> int
end = struct
  type t = int
  
  let of_int x = x
  let to_int x = x
end

let _: SkipInt.t = SkipInt.of_int 42
let _: int = (SkipInt.of_int 42 :> int) (* :> can be used instead of SkipInt.to_int *)
let _: SkipInt.t = (42 :> SkipInt.t) (* Error: Type int is not a subtype of SkipInt.t *)

Solution 2:[2]

It sounds like you might want something like

module Make_int(): sig
  type t [@@immediate]
  val of_int: int -> t
  val to_int: t -> int
  type op := t -> t -> int
  val ( + ): op
  val ( * ) : op
  val ( - ): op
  val ( / ): op
  val ( ~- ): t -> t 
end = struct
   type t = int
   let to_int x = x
   let of_int x = x
   let ( + ) = ( + ) let ( - ) = ( - ) let ( * ) = ( * ) let ( / ) = ( / )
   let ( ~- ) = ( ~- )
end

then any call to Make_int will create a new unboxed int type incompatible with any other type

module Int_1 = Make_int()
module Int_2 = Make_int ()
let fine = Int_1.( of_int 0 + of_int 2 )
let error = Int_1.( of_int 0 + 2 )
let also_error = Int_1.(of_int 0 + Int_2.of_int 1)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 glennsl
Solution 2 octachron