2012-08-06 10 views
15

En C#, puedo definir un método de extensión para una matriz genérica de tipo T como esto:¿Cómo se define una extensión de tipo para T [] en F #?

pero para la vida de mí no puedo encontrar la manera de hacer lo mismo en F #! Intenté type 'a array with, type array<'a> with y type 'a[] with y el compilador no estaba contento con ninguno de ellos.

¿Alguien puede decirme qué es lo correcto para hacer esto en F #?

Claro, puedo hacerlo eclipsando el módulo Array y agregando una función para eso con bastante facilidad, ¡pero realmente quiero saber cómo hacerlo como método de extensión!

+0

¿Qué significa "for the life of me" means :)? – Omu

+0

Extendiendo 'System.Array' fue mi primer pensamiento, pero un parámetro de tipo y un molde serían necesarios a menos que estés de acuerdo con' obj'. – Daniel

+1

@Chuck Norris - significa 'No puedo ... incluso después de intentarlo' – theburningmonk

Respuesta

27

Tienes que escribir el tipo de matriz usando '' marcas de acento grave - como esto:

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 

Editar: La sintaxis type ``[]``<'a> with ... parece estar permitida también. En la fuente F # (prim-types-prelude.fs) puede encontrar la siguiente definición:

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

+1 ¡Buen descubrimiento! ¿Eso está en las especificaciones/documentos? – Daniel

+0

@Daniel: Experimentando. Traté de encontrar algo en las especificaciones/documentos pero no tuve éxito. –

+0

Lo siento, he editado mi pregunta. Gracias. – Daniel

10

Buena pregunta. No puedo encontrar la manera de extender 'T[] pero se puede aprovechar el hecho de que las matrices aplicar IList<_> hacer:

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

Estoy bastante seguro de que no existe una sintaxis legal en F # para agregar un miembro de extensión a los tipos de matriz, por lo que esta es probablemente la mejor alternativa (no puedo pensar en ningún inconveniente, aparte del hecho de que este método también aparece en cualquier otro tipo IList). – Brian

+0

@Daniel - ¡Mierda, tienes razón! 'T [] implementa IList <'T>! ¡No tenía ni idea! Sin embargo, no estoy seguro si eso tiene sentido para mí, una matriz requiere un bloque continuo de memoria, ¿verdad? por lo tanto, las operaciones de adición seguramente tendrán que volver a asignar para toda la nueva matriz cada vez, lo cual me parece como algo que debería desalentar y alentar el uso de la Lista (que tiene un búfer interno que administra). – theburningmonk

+3

'IList <_>' miembros mutantes, 'Add' /' Remove', etc, tira 'NotSupportedException'. Pruebe: '([| 1 |]:> System.Collections.Generic.IList <_>) .Add (2)' – Daniel

Cuestiones relacionadas