Как написать функцию, принимающую переменное число аргументов в F #
У меня есть функция на С#, и я хотел бы перенести ее (среди некоторых других вещей) на F #, только ради этого. К сожалению, я просто ударил случай, для которого, кажется, нет способа выразить это в F #: Возьмите эту функцию С#
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)
но называя это от С# ожидает Microsoft.FSharp.Collections.List
. Возможно ли, чтобы он ожидал a params T[]
, и если да, то как?
Ответы
Ответ 1
Массив 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 # или код С#. Тот же компромисс будет применяться при разработке функций более высокого порядка, использовании кортежей, использовании дискриминированных объединений и т.д. С# не может выразить большинство вещей, а F # в настоящее время не поддерживает некоторые из маленьких битов сахара С# (дерево выражений, написанное в компилятор, например).
Ответ 2
Вы хотите вызвать этот метод из F # или С#? Это сообщение hubFS, похоже, указывает, что F # не поддерживает массивы параметров на вызывающей стороне, но я подозреваю, что вы используете стандартную аннотацию типа для параметр, чтобы сделать его массивом, а также украсить его ParamArrayAttribute, вы должны иметь возможность вызывать его с переменными аргументами из С#.
Не могу сказать, что я видел, как украсить параметр атрибутами в F #, но я могу охотиться, если вы хотите... Этот блог post дает несколько примеров, но не на уровне параметров.