Перечислимый#перебор прототипа в F #?
-
09-06-2019 - |
Вопрос
В JavaScript, используя библиотеку Prototype, возможна следующая функциональная конструкция:
var words = ["aqueous", "strength", "hated", "sesquicentennial", "area"];
words.pluck('length');
//-> [7, 8, 5, 16, 4]
Обратите внимание, что этот пример кода эквивалентен
words.map( function(word) { return word.length; } );
Я задавался вопросом, возможно ли что-то подобное в F#:
let words = ["aqueous"; "strength"; "hated";"sesquicentennial"; "area"]
//val words: string list
List.pluck 'Length' words
//int list = [7; 8; 5; 16; 4]
без необходимости писать:
List.map (fun (s:string) -> s.Length) words
Мне это показалось бы весьма полезным, потому что тогда вам не нужно писать функции для каждого свойства, чтобы получить к ним доступ.
Решение
Я видел ваш запрос в списке рассылки F #.Надеюсь, я смогу помочь.
Вы могли бы использовать расширение типа и отражение, чтобы разрешить это.Мы просто расширяем тип универсального списка с помощью функции pluck.Тогда мы можем использовать pluck() в любом списке.Неизвестное свойство вернет список со строкой ошибки в качестве единственного содержимого.
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"
который выдает следующий результат в интерактивном окне:
> 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'"]
с наилучшими пожеланиями,
Данньяшер
> > > > >
ПРИМЕЧАНИЕ:При использовании <pre
> угловые скобки вокруг
<'a>не показывалось, хотя в окне предварительного просмотра все выглядело нормально.Ответный ход у меня не сработал.Пришлось прибегнуть к раскрашенной версии, в которой все неправильно.Я не думаю, что буду публиковать здесь сообщение снова, пока синтаксис FSharp не будет полностью поддержан.
Другие советы
Прототип pluck
использует преимущества этого в Javascript object.method()
это то же самое , что object[method]
.
К сожалению, вы не можете позвонить String.Length
либо потому, что это не статический метод.Однако вы можете использовать:
#r "FSharp.PowerPack.dll"
open Microsoft.FSharp.Compatibility
words |> List.map String.length
Однако, используя Compatibility
вероятно, это еще больше запутает людей, просматривающих ваш код.