将OCaml转换为F#:如何转换OCaml Format模块的类型

时间:2012-09-10 21:34:06

标签: types f# ocaml external

我正在将OCaml Format module转换为F#;见我的earlier question

开始时我改变了

  

类型大小

     

external size_of_int:int - > size =“%identity”

     

external int_of_size:size - > int =“%identity”

  

让size_of_int = sizeof <int&gt;

以及我知道的一些其他调整不正确,但它允许我转换所有与open_box相关的代码,close_box期望这三行。

现在我必须更改这三行,以便我可以测试我转换的格式模块的子集。

我知道在外部使用size_of_int和int_of_size的行可能依赖于F#核心中的某些功能。我也知道转换可能会忽略%identity

我最好的猜测是我只需要用size_of_int和int_of_size创建一个名为size的简单类型,但是如何?

修改

基于Jeffrey Scofield的回答,我能够创建以下F#代码。

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

允许我的Format模块子集成功编译。

编辑

Jack,如下所述,其版本为FSharpx.Compatibility.OCaml.Format.Format.fs 我没有对它进行测试,但它是我目前发现的最具竞争力的版本。

2 个答案:

答案 0 :(得分:5)

这些行:

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

创建一个与int相同的抽象类型。转换功能 是无操作(身份功能)。我不知道F#成语,但在 OCaml你可以使用一个接口文件,并通过“%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

希望这更容易转化为F#。

答案 1 :(得分:2)

作为参考,您可以使用另一种更安全的方式在F#中处理此代码:使用度量单位类型注释。

当你在F#中编写type size = int时,size只是int的别名 - 所以F#编译器会很乐意让你混合和匹配它们。例如:

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

如果您想要更多类型安全性,可以定义度量单位类型Size并像这样使用它:

[<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

如果你从OCaml转到F#,这可能有些熟悉。 F#中的度量单位类型在编译时被删除,但它们有助于减少代码中的简单数学错误 - 幻象类型可以在OCaml中用于相同的目的。