内联函数和类型扩展

时间:2015-10-02 18:52:33

标签: f# inline

考虑我有两种不同的类型:

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我无法更改BarFoo,因为它们是图书馆代码的一部分。

这是我第一次尝试使用类型扩展和内联函数,如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类型定义的情况下解决我的问题?

2 个答案:

答案 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"

这不是最好的,也不是非常通用的解决方案,但至少它可行。