Enumerable#pluck del prototipo in F#?
-
09-06-2019 - |
Domanda
In JavaScript, utilizzando la libreria Prototype, è possibile la seguente costruzione funzionale:
var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"];
words.pluck('length');
//-> [7, 8, 5, 16, 4]
Tieni presente che questo codice di esempio è equivalente a
words.map( function(word) { return word.length; } );
Mi chiedevo se qualcosa di simile fosse possibile in F#:
let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"]
//val words: string list
List.pluck 'Length' words
//int list = [7; 8; 5; 16; 4]
senza dover scrivere:
List.map (fun (s:string) -> s.Length) words
Questo mi sembrerebbe molto utile perché in questo modo non è necessario scrivere funzioni per ogni proprietà per accedervi.
Soluzione
Ho visto la tua richiesta sulla mailing list F#.Spero di poter aiutare.
È possibile utilizzare l'estensione del tipo e la riflessione per consentire ciò.Estendiamo semplicemente il tipo elenco generico con la funzione pluck.Quindi possiamo usare pluck() su qualsiasi lista.Una proprietà sconosciuta restituirà un elenco con la stringa di errore come unico contenuto.
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"
che produce il seguente risultato nella finestra interattiva:
> 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'"]
cordiali saluti,
Danny Asher
> > > > >
NOTA:Quando si usa <pre
> le parentesi angolari intorno
<'a>non è stato mostrato anche se nella finestra di anteprima sembrava a posto.Il backtick non ha funzionato per me.Ho dovuto ricorrere alla versione colorata che è tutta sbagliata.Non penso che pubblicherò di nuovo qui finché la sintassi FSharp non sarà completamente supportata.
Altri suggerimenti
Il prototipo pluck
ne approfitta in Javascript object.method()
equivale a object[method]
.
Purtroppo non puoi chiamare String.Length
sia perché non è un metodo statico.Puoi comunque utilizzare:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Compatibility
words |> List.map String.length
Tuttavia, utilizzando Compatibility
probabilmente renderà le cose più confuse per le persone che guardano il tuo codice.