Как определить расширение типа для T [] в F #?

В С# я могу определить метод расширения для общего массива типа T следующим образом:

public static T GetOrDefault<T>(this T[] arr, int n)
{
    if (arr.Length > n)
    {
        return arr[n];
    }

    return default(T);
}

но для жизни меня не могу понять, как сделать то же самое в F #! Я пробовал type 'a array with, type array<'a> with и type 'a[] with, и компилятор не был доволен ни одним из них.

Может ли кто-нибудь сказать мне, что право делать это в F #?

Конечно, я могу сделать это, затмив модуль Array и добавить функцию для этого достаточно легко, но я действительно хочу знать, как это сделать как метод расширения!

Ответ 1

Вам нужно написать тип массива, используя "обратные метки" - вот так:

type 'a ``[]`` with
  member x.GetOrDefault(n) = 
    if x.Length > n then x.[n]
    else Unchecked.defaultof<'a>

let arr = [|1; 2; 3|]
arr.GetOrDefault(1) //2
arr.GetOrDefault(4) //0

Изменить. Синтаксис type ``[]``<'a> with ... также допускается. В источнике F # (prim-types-prelude.fs) вы можете найти следующее определение:

type ``[]``<'T> = (# "!0[]" #)

Ответ 2

Хороший вопрос. Я не могу понять, как расширить 'T[], но вы можете воспользоваться тем, что массивы реализуют IList<_> :
type System.Collections.Generic.IList<'T> with
  member x.GetOrDefault(n) = 
    if x.Count > n then x.[n]
    else Unchecked.defaultof<'T>

let arr = [|1; 2; 3|]
arr.GetOrDefault(1) //2
arr.GetOrDefault(4) //0