考虑我有两种不同的库类型:
df2 <- function(A,x) {
# A is the name of the data.frame() and x is the rank No
df <- A[A[,4]==x,]
return(df)
}
> df2(df,2)
county park hectares parkrank
1 QU Downtown 12 2
6 GY GarbagePile 6 2
8 AN BigHill 52 2
我想实现适用于type Foo = { foo : string }
type Bar = { bar : int32 }
或zoo
实例的通用函数Foo
。 我无法更改Bar
和Foo
,因为它们是图书馆代码的一部分。
这是我第一次尝试使用类型扩展和内联函数,如here所述:
Bar
为什么内联函数定义不依赖于类型扩展?如何在不更改初始// Library.fs
module Library
type Foo = { foo : string }
type Bar = { bar : int32 }
// Program.fs
type Foo with
static member zoo (f : Foo) = "foo"
type Bar with
static member zoo (b : Bar) = "bar"
let inline zoo (x : ^t) =
(^t : (static member zoo : ^t -> string) x)
let f = zoo { foo = "1" } // error FS0001: The type 'Foo' does not support the operator 'zoo'
和Foo
类型定义的情况下解决我的问题?
答案 0 :(得分:11)
使用方法重载。
扩展方法的问题在于solving member constraints时不会考虑它们。
所以你可以使用方法重载,如你自己的答案中所示,或者你可以通过使用中间类型和中间方法(在这种情况下为简单的操作符)来进一步创建内联泛型函数来做:
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" }
您可以more details了解其工作原理。
请注意,此函数将被内联,因此,例如,您将无法从C#调用它,如果需要,请不要使用函数,使用简单和标准方法重载。
答案 1 :(得分:1)
到目前为止我能做的最好的事情是
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"
这不是最好的,也不是非常通用的解决方案,但至少它可行。