如何在 F# 中编写一个带有可变数量参数的函数 [英] Howto write a function taking variable number of arguments in F#
问题描述
我在 C# 中有一个函数,我想将它(以及其他一些东西)移植到 F#,只是为了这样做.不幸的是,我刚刚遇到了一个似乎无法在 F# 中表达这一点的案例:使用这个 C# 函数
I've got a function in C#, and I'd like to port it (among some other stuff) over to F#, just for the sake of doing it. Unfortunately, I just hit a case for which there seems to be no way to express this in F#: Take this C# function
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# 中指定可变参数列表.我试过这个:
I'd thought this would be pretty easy, but I don't understand how I would specify a variable argument list in F#. I have tried this:
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[]
,如果是,如何?
but calling that from C# expects a Microsoft.FSharp.Collections.List
. Is it possible to get it expect a params T[]
, and if so, how?
推荐答案
正如 Jon 所指出的,params 数组只是一个带有属性的数组.在参数前添加属性.
A params array is simply an array with an attribute, as Jon notes. Add the attribute before the parameter.
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# 的一些小糖点(表达树在例如编译器).
But... pattern matching doesn't work on the array type. You could write an active pattern to help. Basically, you have to decide what's more important: the F# code or the C# code. The same tradeoff will apply as you design higher order functions, use tuples, use discriminated unions, etc. C# can't express most things, and F# doesn't currently support some of the little bits of sugar C# has (Expression Tree writing in the compiler, for example).
这篇关于如何在 F# 中编写一个带有可变数量参数的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!