3

我正在将 OCaml格式模块转换为 F#;请参阅我之前的问题

开始我改变了

字体大小

外部 size_of_int : int -> size = "%identity"

外部 int_of_size : 大小 -> int = "%identity"

让 size_of_int = sizeof <int>

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

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

我知道带有 size_of_int 和 int_of_size 而 external 的行可能依赖于 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 模块的子集能够成功编译。

编辑

下面回答的JackFSharpx.Compatibility.OCaml.Format.Format.fs有一个版本, 我没有测试过,但它是我目前找到的最完整的版本。

4

2 回答 2

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#。

于 2012-09-10T21:53:05.997 回答
2

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

当您type size = int在 F# 中编写时,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 中可以出于相同目的使用幻像类型。

于 2012-09-11T18:45:07.500 回答