F# 是否具有行多态性(或类似的东西?)

Does F# have row polymorphism (or something similar?)

F# 是否具有行多态性或类似的东西?具体来说,在OCaml中,我们可以写一个像

这样的函数
# let foo x = x#num+2;;
val foo : < num : int; .. > -> int = <fun>

基本上,函数 foo 可以接受任何包含类型 int 的方法 num 的对象。我不确定如何在 F# 中做类似的事情。如果可能的话,我想避免通过继承进行显式子类型化。具体来说,我不是寻找这样的东西:

[<AutoOpen>]
module Foo

[<AbstractClass>]
type foo() =
    abstract member num : int

type foo1() =
    inherit foo()
    override this.num = 2
    member this.char = 'a'

type foo2() =
    inherit foo()
    override this.num = 3
    member this.string = "abbacadabba"

let f (x:foo) = x.num + 2

原因是即使我们可以在 f 中使用 foo1foo2 类型的对象,我们也无法访问它们的其他成员,charstring,分别。为了重新获得这些信息,我们必须玩双重派遣技巧,例如使用访问者模式,我正在努力避免这种情况。基本上,我正在尝试获得类似行多态性而不是子类型化的东西。

这是一种方法:

let inline foo (a: ^a) = 
    let x = (^a : (member num: int) (a))
    x + 2

type monkey() =
    member x.num = 2
type pig() =
    member x.num = 3

let x = monkey()
let y = pig()

foo x // = 2+2=4
foo y // = 3+2=5