Enumerable#pluck do protótipo em F#?
-
09-06-2019 - |
Pergunta
Em JavaScript, utilizando a biblioteca Prototype, é possível a seguinte construção funcional:
var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"];
words.pluck('length');
//-> [7, 8, 5, 16, 4]
Observe que este código de exemplo é equivalente a
words.map( function(word) { return word.length; } );
Eu me perguntei se algo semelhante é possível em F#:
let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"]
//val words: string list
List.pluck 'Length' words
//int list = [7; 8; 5; 16; 4]
sem precisar escrever:
List.map (fun (s:string) -> s.Length) words
Isso me pareceria bastante útil porque você não precisa escrever funções para cada propriedade para acessá-las.
Solução
Vi sua solicitação na lista de discussão do F#.Espero poder ajudar.
Você poderia usar extensão de tipo e reflexão para permitir isso.Simplesmente estendemos o tipo de lista genérico com a função pluck.Então podemos usar pluck() em qualquer lista.Uma propriedade desconhecida retornará uma lista com a string de erro como único conteúdo.
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"
que produz o seguinte resultado na janela interativa:
> 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'"]
Atenciosamente,
Danny Asher
> > > > >
OBSERVAÇÃO:Ao usar <pre
> os colchetes angulares ao redor
<'a>não apareceu na janela de visualização, parecia bom.O backtick não funcionou para mim.Tive que recorrer a você a versão colorida que está toda errada.Acho que não postarei aqui novamente até que a sintaxe do FSharp seja totalmente suportada.
Outras dicas
Protótipo pluck
aproveita isso em Javascript object.method()
é o mesmo que object[method]
.
Infelizmente você não pode ligar String.Length
ou porque não é um método estático.No entanto, você pode usar:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Compatibility
words |> List.map String.length
No entanto, usando Compatibility
provavelmente tornará as coisas mais confusas para as pessoas que olham para o seu código.