我在C#中有一个函数,我想将它(在其他一些东西中)移植到F#,只是为了做到这一点。不幸的是,我只是打了一个案例,似乎没有办法在F#中表达这个:拿这个C#函数
public static T Min<T>(params T[] p) where T : IComparable
{
T m1 = p[0];
foreach (T v in p)
{
m1 = (m1.CompareTo(v) < 0) ? m1 : v;
}
return m1;
}
我认为这很容易,但我不明白如何在F#中指定变量参数列表。我试过这个:
let rec Min l =
match l with
| [] -> 0 // should throw exception here
| [v] -> v
| (h::t) -> min h (Min t)
但是从C#调用它需要Microsoft.FSharp.Collections.List
。它是否有可能让它期望params T[]
,如果是,如何?
答案 0 :(得分:24)
如Jon所说,params数组只是一个带属性的数组。在参数之前添加属性。
let test ([<ParamArray>] arr : 'a array) =
if arr.Length = 0 then invalid_arg "arr"
// ....
您无需指定类型:
let test ([<ParamArray>] arr) = ... // lets type inference do its thing
但是......模式匹配对数组类型不起作用。您可以编写一个活动模式来提供帮助。基本上,您必须决定什么更重要:F#代码或C#代码。当您设计高阶函数,使用元组,使用有区别的联合等时,同样的权衡将适用.C#不能表达大多数事物,而F#目前不支持C#中的一些小部分(表达式树写入例如,编译器。
答案 1 :(得分:6)
您想要从F#或C#调用此方法吗? This hubFS post似乎表明F#不支持调用端的参数数组,但我怀疑你是否为参数使用普通类型注释使其成为一个数组,并用ParamArrayAttribute来装饰它,您应该可以使用C#中的可变参数调用它。
不能说我已经看过如何使用F#中的属性来装饰一个参数,但是如果你想要我可以寻找...... This blog post给出了几个例子,但不是在参数级别