2012-08-06 13 views
15

W języku C#, można zdefiniować metodę rozszerzenia dla rodzajowego tablicy typu T tak:Jak zdefiniować rozszerzenie typu dla T [] w F #?

ale dla życia mnie nie mogę dowiedzieć się, jak zrobić to samo w F #! Próbowałem type 'a array with, type array<'a> with i type 'a[] with i kompilator nie był zadowolony z żadnego z nich.

Czy ktoś może mi powiedzieć, jakie jest prawo do tego w F #?

Jasne, mogę to zrobić, przesłoniwszy moduł Array i dodając do tego funkcję wystarczająco łatwo, ale naprawdę chcę wiedzieć, jak to zrobić jako metodę rozszerzenia!

+0

co oznacza "na życie mnie" oznacza :)? – Omu

+0

Przedłużenie 'System.Array' było moją pierwszą myślą, ale parametr typu i rzutowanie będą potrzebne, chyba że jesteś w porządku z' obj'. – Daniel

+1

@Chuck Norris - oznacza "Nie mogę ... nawet po tym, jak bardzo się postarałem" – theburningmonk

Odpowiedz

27

Trzeba napisać typ tablicy za pomocą „grawis znaki” - tak:

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 

Edytuj: Wydaje się, że dozwolona jest również składnia type ``[]``<'a> with .... W źródle F # (prim-types-prelude.fs) można znaleźć następującą definicję:

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

+1 Dobra okazja! Czy to w specyfikacji/dokumentach? – Daniel

+0

@Daniel: Eksperymentowanie. Próbowałem znaleźć cokolwiek w specyfikacji/dokumentach, ale bez powodzenia. –

+0

Przepraszam, zredagowałem moje pytanie. Dzięki. – Daniel

10

Dobre pytanie. Nie mogę dowiedzieć się, jak rozszerzyć 'T[] ale można skorzystać z faktu, że tablice wdrożyć IList<_> zrobić:

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 
+1

Jestem prawie pewien, że nie ma żadnej prawnej składni w F #, aby dodać członka rozszerzenia do typów tablic, więc jest to prawdopodobnie najlepsza alternatywa (od ręki nie mogę wymyślić żadnych wad, poza tym, że ta metoda pojawia się również w innych typach IListów). – Brian

+0

@Daniel - Święty Boże, masz rację! "T [] implementuje IList <'T>! Nie mam pojęcia! nie jestem pewien, czy to ma dla mnie sens, tablica ma ciągły blok pamięci, prawda? więc operacje dodawania na pewno będą musiały ponownie przydzielić dla całej nowej tablicy za każdym razem, co wydaje mi się czymś, co powinno zniechęcić i zachęcić do korzystania z Listy (która ma wewnętrzny bufor, którym zarządza). – theburningmonk

+3

'IList <_>' muting members, 'Add' /' Remove', etc, throw 'NotSupportedException'. Spróbuj: '([| 1 |]:> System.Collections.Generic.IList <_>) .Dodaj (2)' – Daniel

Powiązane problemy