F# 内联函数和类型扩展

F# 内联函数和类型扩展,f#,inline,F#,Inline,假设我有两种不同的库类型: 我想实现一个通用函数zoo,它可以用于Foo或Bar实例我不能更改Foo和Bar,因为它们是库代码的一部分。 这是我第一次尝试使用类型扩展和内联函数,如下所述: 为什么内联函数定义不依赖于类型扩展?如果不更改初始的Foo和Bar类型定义,我如何解决问题?到目前为止,我能得到的最好的结果是 type Ext = static member zoo (f : Foo) = "foo" static member zoo (b : Bar) = "bar"

假设我有两种不同的库类型:

我想实现一个通用函数
zoo
,它可以用于
Foo
Bar
实例我不能更改
Foo
Bar
,因为它们是库代码的一部分。

这是我第一次尝试使用类型扩展和内联函数,如下所述:


为什么内联函数定义不依赖于类型扩展?如果不更改初始的
Foo
Bar
类型定义,我如何解决问题?

到目前为止,我能得到的最好的结果是

type Ext =
    static member zoo (f : Foo) = "foo"
    static member zoo (b : Bar) = "bar"

let f = Ext.zoo { foo = "1" } // "foo"
let b = Ext.zoo { bar = 2 } // "bar"
这不是最好的,也不是非常通用的解决方案,但至少它是有效的。

使用方法重载

扩展方法的问题在于,在进行扩展时没有考虑它们

因此,您可以使用方法重载,如您自己的答案中所示,或者您可以更进一步,通过使用中间类型和中间方法(为了简单起见,在本例中为运算符)来创建内联泛型函数:

type T = T with
    static member ($) (T, x:Foo) = "foo"
    static member ($) (T, x:Bar) = "bar"

let inline zoo x = T $ x

let f = zoo { foo = "1" }
这是关于这是如何工作的

请注意,此函数将是内联的,因此,例如,您将无法从C#调用它,如果需要,请不要使用函数,请使用简单和标准的方法重载

type Ext =
    static member zoo (f : Foo) = "foo"
    static member zoo (b : Bar) = "bar"

let f = Ext.zoo { foo = "1" } // "foo"
let b = Ext.zoo { bar = 2 } // "bar"
type T = T with
    static member ($) (T, x:Foo) = "foo"
    static member ($) (T, x:Bar) = "bar"

let inline zoo x = T $ x

let f = zoo { foo = "1" }