在F#中实现幻像类型

时间:2010-08-27 11:28:04

标签: f#

Ocaml程序员可以使用所谓的“幻像类型”来使用类型系统强制执行某些约束。可以在http://ocaml.janestreet.com/?q=node/11找到一个很好的例子。

语法type readonly在F#中不起作用。它可以替换为定义为type readonly = ReadOnlyDummyValue的伪幻像类型,以便在上述博客文章中实现技巧。

有没有更好的方法来定义F#中的幻像类型?

1 个答案:

答案 0 :(得分:15)

我认为仅使用type somename定义类型在F#中不起作用。 F#编译器需要从声明中生成一些.NET类型,而F#规范没有明确定义幻像类型应该发生什么。

您可以在实现文件(.fs)中创建具体类型(例如,使用type somename = ReadOnlyDummyValue),并通过仅将type somename添加到接口文件(.fsi)来隐藏该类型的内部。这样你就会非常接近幻像类型 - 文件外部的用户将看不到该类型的内部。

另一个吸引人的选择是使用接口。这对我来说听起来很合乎逻辑,因为空接口可能是您可以声明的最简单类型(并且它不会引入任何虚拟标识符)。空接口看起来像这样:

type CanRead = interface end
type CanWrite = interface end

有趣的是,在这种情况下,您还可以创建继承的接口:

type CanReadWrite = 
  inherit CanRead
  inherit CanWrite

然后你可以编写一个函数,它可以获取Ref<CanRead, int>类型的值,但也可以编写Ref<CanReadWrite, int>类型的值(因为这些值也支持读取):

let foo (arg:Ref<#CanRead, int>) = // ...    

这似乎是有用的东西。我真的很感兴趣是否可以在OCaml中完成(因为它依赖于F#支持接口和继承)。