Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting OCaml to F#: How to convert type for OCaml Format module

I am converting the OCaml Format module to F#; see my earlier question.

To get started I changed

type size

external size_of_int : int -> size = "%identity"

external int_of_size : size -> int = "%identity"

to

let size_of_int = sizeof<int>

and a few other adjustments which I know is not correct, but it allowed me to convert all code related to open_box and close_box expect these three lines.

Now I have to just change these three lines so that I can test the subset of the format module that I did convert.

I know that the lines with size_of_int and int_of_size while external will probably rely on some function in the F# core. I also know that %identity can probably be ignored for the conversion.

My best guess is that I only need to create a simple type named size with size_of_int and int_of_size, but how?

EDIT

Based on answer by Jeffrey Scofield I was able to create the following F# code.

type size =
  interface
    abstract size_of_int : int -> size
    abstract int_of_size : size -> int
  end

type size = int
let size_of_int i = i
let int_of_size s = s

which allowed my subset of the Format module to successfully compile.

EDIT

Jack, who answered below, has a version at FSharpx.Compatibility.OCaml.Format.Format.fs I havent' tested it, but it is the most compelete version I have found at present.

like image 705
Guy Coder Avatar asked Dec 01 '25 09:12

Guy Coder


2 Answers

These lines:

type size
external size_of_int : int -> size = "%identity"
external int_of_size : size -> int = "%identity"

Create an abstract type that is identical to int. The conversion functions are no-ops (the identity function). I don't know the F# idioms, but in OCaml you can use an interface file and avoid the cleverness with "%identity".

(* Interface file *)
type size
val size_of_int : int -> size
val int_of_size : size -> int

(* Implementation file *)
type size = int

let size_of_int i = i
let int_of_size s = s

Hopefully this translates more readily into F#.

like image 157
Jeffrey Scofield Avatar answered Dec 03 '25 08:12

Jeffrey Scofield


For reference, there's another, more type-safe way you can handle this code in F#: by using unit-of-measure type annotations.

When you write type size = int in F#, size is simply an alias for int -- so the F# compiler will happily allow you to mix and match them. For example:

let someSize : size = 10
let badSum = someSize + 3  // 'someSize' is used like another other 'int'

If you wanted a bit more type safety, you could define a unit-of-measure type Size and use it like this:

[<Measure>] type Size
type size = int<Size>

let inline size_of_int i =
    LanguagePrimitives.Int32WithMeasure<Size> i
let inline int_of_size s = int s

// Now, using a variable of type 'size' where an 'int' is expected
// (or vice versa) will result in a compilation error.
let someSize = size_of_int 10
let badSum = someSize + 3  // compilation error here

If you're coming over to F# from OCaml, this may be somewhat familiar. Unit-of-measure types in F# are erased at compile-time, but they help reduce simple math mistakes in code -- phantom types can be used in OCaml for the same purpose.

like image 27
Jack P. Avatar answered Dec 03 '25 06:12

Jack P.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!