Ocaml程序员可以使用所谓的"幻像类型"来使用类型系统强制执行某些约束.一个很好的例子可以在http://ocaml.janestreet.com/?q=node/11找到.
语法type readonly
在F#中不起作用.它可以被定义为伪幻像类型type readonly = ReadOnlyDummyValue
,以便在上述博客文章中实现技巧.
有没有更好的方法来定义F#中的幻像类型?
Tom*_*cek 16
我认为仅使用定义类型type somename
在F#中不起作用.F#编译器需要从声明中生成一些.NET类型,而F#规范没有明确定义幻像类型应该发生什么.
您可以type somename = ReadOnlyDummyValue
在实现文件(.fs)中创建具体类型(例如with ),并通过仅添加type somename
到接口文件(.fsi)来隐藏类型的内部.通过这种方式,您可以非常接近幻像类型 - 文件外部的用户将看不到该类型的内部.
另一个吸引人的选择是使用接口.这对我来说听起来很合乎逻辑,因为空接口可能是您可以声明的最简单类型(并且它不会引入任何虚拟标识符).空接口看起来像这样:
type CanRead = interface end
type CanWrite = interface end
Run Code Online (Sandbox Code Playgroud)
在这种情况下,有趣的是,您还可以创建继承的接口:
type CanReadWrite =
inherit CanRead
inherit CanWrite
Run Code Online (Sandbox Code Playgroud)
然后你可以编写一个函数,它可以获取类型的值,Ref<CanRead, int>
但也可以编写类型的值Ref<CanReadWrite, int>
(因为这些值也支持读取):
let foo (arg:Ref<#CanRead, int>) = // ...
Run Code Online (Sandbox Code Playgroud)
这似乎是有用的东西.我真的很感兴趣是否可以在OCaml中完成(因为它依赖于F#支持接口和继承).