¿Enumerable#pluck del prototipo en F#?
-
09-06-2019 - |
Pregunta
En JavaScript, utilizando la biblioteca Prototype, es posible la siguiente construcción funcional:
var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"];
words.pluck('length');
//-> [7, 8, 5, 16, 4]
Tenga en cuenta que este código de ejemplo es equivalente a
words.map( function(word) { return word.length; } );
Me preguntaba si algo similar es posible en F#:
let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"]
//val words: string list
List.pluck 'Length' words
//int list = [7; 8; 5; 16; 4]
sin tener que escribir:
List.map (fun (s:string) -> s.Length) words
Esto me parecería bastante útil porque entonces no es necesario escribir funciones para cada propiedad para acceder a ellas.
Solución
Vi su solicitud en la lista de correo de F#.Espero poder ayudar.
Podrías usar extensión de tipo y reflexión para permitir esto.Simplemente ampliamos el tipo de lista genérica con la función de selección.Entonces podemos usar pluck() en cualquier lista.Una propiedad desconocida devolverá una lista con la cadena de error como único contenido.
type Microsoft.FSharp.Collections.List<'a> with
member list.pluck property =
try
let prop = typeof<'a>.GetProperty property
[for elm in list -> prop.GetValue(elm, [| |])]
with e->
[box <| "Error: Property '" + property + "'" +
" not found on type '" + typeof<'a>.Name + "'"]
let a = ["aqueous"; "strength"; "hated"; "sesquicentennial"; "area"]
a.pluck "Length"
a.pluck "Unknown"
lo que produce el siguiente resultado en la ventana interactiva:
> a.pluck "Length" ;; val it : obj list = [7; 8; 5; 16; 4] > a.pluck "Unknown";; val it : obj list = ["Error: Property 'Unknown' not found on type 'String'"]
Un cordial saludo,
dannyasher
> > > > >
NOTA:Cuando usas <pre
> los corchetes angulares alrededor
<'a>Aunque no se mostró en la ventana de vista previa, se veía bien.La comilla invertida no me funcionó.Tuve que recurrir a la versión coloreada, que está completamente mal.No creo que vuelva a publicar aquí hasta que la sintaxis de FSharp sea totalmente compatible.
Otros consejos
Prototipos pluck
aprovecha eso en Javascript object.method()
es lo mismo que object[method]
.
Lamentablemente no puedes llamar String.Length
ya sea porque no es un método estático.Sin embargo puedes usar:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Compatibility
words |> List.map String.length
Sin embargo, usando Compatibility
probablemente hará que las cosas sean más confusas para las personas que miran su código.