满足隐式接口的记录无需重新实现

The*_*ack 4 f# records interface

看到记录已经为其字段设置了公共Getter /(Setter),是否可以指定记录满足匹配的接口而无需重新实现它?

例如:

type IText = 
    abstract text : string with get,set

type TextRec = 
{ 
mutable text : string
}
Run Code Online (Sandbox Code Playgroud)

现在看到Record已经隐式实现了这个接口,我想在记录中放置一个"继承IText"或"接口IText"(没有正文),但看起来我不能这样做.实际上,我相信我必须通过将其添加到记录中来重新实现接口:

interface IText with
    member this.text
        with get()  = this.text
        and set(v)  = this.text <- v
Run Code Online (Sandbox Code Playgroud)

谢谢

Tom*_*cek 7

F#目前不支持隐式接口实现(甚至不支持类),但它是经常请求的功能之一,因此将来可能会发生.我当然明白为什么这会有用.

我认为没有任何好的解决方法 - 最好的选择可能是编写实现接口所需的额外代码.

如果你想冒险,你可以尝试编写一个"包装"功能,从一个提供所需成员的值创建一个接口实现.使用静态成员约束,您可以要求成员在那里(没有实际实现接口):

type IText = 
  abstract Text : string with get, set

let inline wrap (a:^T) =
  { new IText with
      member x.Text 
        with get() = (^T : (member Text : string) (a)) 
        and set(v) = (^T : (member set_Text : string -> unit) (a, v)) }
Run Code Online (Sandbox Code Playgroud)

静态成员约束(在实现中使用wrap)主要用于通用数值计算,因此这有点延伸(当然是高级F#特性),但它可以解决这个问题:

type Rect = { mutable Text : string }
let i = wrap { Text = "Hi" }
i.Text <- i.Text + " there!"
Run Code Online (Sandbox Code Playgroud)