How to define a type extension for T[] in F#?

2019-01-18 10:32发布

In C#, I can define an extension method for a generic array of type T like this:

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

    return default(T);
}

but for the life of me I can't figure out how to do the same in F#! I tried type 'a array with, type array<'a> with and type 'a[] with and the compiler wasn't happy with any of them.

Can anyone tell me what's the right to do this in F#?

Sure, I can do this by overshadowing the Array module and add a function for that easily enough, but I really want to know how to do it as an extension method!

2条回答
2楼-- · 2019-01-18 11:03

Good question. I can't figure out how to extend 'T[] but you can take advantage of the fact that arrays implement IList<_> to do:

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
查看更多
SAY GOODBYE
3楼-- · 2019-01-18 11:16

You have to write the array type using 'backtick marks' - like this:

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

Edit: The syntax type ``[]``<'a> with ... seems to be allowed as well. In the F# source (prim-types-prelude.fs) you can find the following definition:

type ``[]``<'T> = (# "!0[]" #)
查看更多
登录 后发表回答