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.
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#.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With