C# – Howto write a function taking variable number of arguments in F#

%fc

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;
}

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)

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?

Best Answer

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"
    // ....

You don't need to specify the type:

let test ([<ParamArray>] arr) = ... // lets type inference do its thing

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).

Related Topic