Как написать функцию, принимающую переменное число аргументов в F # - PullRequest
26 голосов
/ 23 марта 2009

У меня есть функция в 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[], и если да, то как?

Ответы [ 2 ]

25 голосов
/ 23 марта 2009

Массив 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 # (запись дерева выражений в компилятор, например).

6 голосов
/ 23 марта 2009

Вы хотите вызвать этот метод из F # или C #? Этот пост hubFS , кажется, указывает, что F # не поддерживает массивы параметров на вызывающей стороне, но я подозреваю, что если вы используете нормальную аннотацию типа для параметра, чтобы сделать его массивом, а также украсить его с помощью ParamArrayAttribute , вы должны иметь возможность вызывать его с переменными аргументами из C #.

Не могу сказать, что я видел, как украсить параметр с атрибутами в F #, но я могу охотиться, если хотите ... В этом блоге приводятся несколько примеров, но не на уровне параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...