我发现以下C#扩展方法非常有用:
public static bool In<T>(this T x, params T[] xs)
{
return xs.Contains(x);
}
允许进行C#调用,例如
var s = "something else";
var rslt = s.In("this","that","other") ? "Yay" : "Boo";
和
var i = 1;
var rslt = i.In(1,2,3) ? "Yay" : "Boo";
我一直试图想出一个F#(近似)等价物,例如:
let s = "something else"
let rslt = if s.In("this","that","other") then "Yay" else "Boo"
似乎我需要类似的东西:
type 'T with
static member this.In([ParamArray] xs : 'T )
{
return xs.Contains(x);
}
但这不是合法的F#语法。我无法看到如何在F#中的泛型类上声明扩展方法。可能吗?或者有更好的方法来实现类似的结果吗? (我想我可以在C#项目中链接并从F#中调用它,但那会欺骗!: - )
我能想到的最好的是:
let inline In (x : 'a, [<ParamArray>] xs : 'a[]) = Array.Exists( xs, (fun y -> x = y) )
我希望允许这样的电话(无论如何都不能接受):
if In(ch, '?', '/') then "Yay" else "Boo"
但实际上需要:
if In(ch, [| '?'; '/' |]) then "Yay" else "Boo"
暗示ParamArray属性被忽略(原因我还没有理解)。
答案 0 :(得分:2)
Fwiw,最新版本的F#(3.1)包含了我之后的所有内容(耶!):
[<Extension>]
type ExtraCSharpStyleExtensionMethodsInFSharp () =
[<Extension>]
static member inline In(x: 'T, xs: seq<'T>) = xs |> Seq.exists (fun o -> o = x)
[<Extension>]
static member inline Contains(xs: seq<'T>, x: 'T) = xs |> Seq.exists (fun o -> o = x)
[<Extension>]
static member inline NotIn(x: 'T, xs: seq<'T>) = xs |> Seq.forall (fun o -> o <> x)
提供用法
if s.In(["this","that","other"]) then ....
if (["this","that","other"]).Contains(s) then ...
等