我正在将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 我没有对它进行测试,但它是我目前发现的最具竞争力的版本。
答案 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中用于相同的目的。