Другой порядок аргументов для получения N-го элемента Array, List или Seq
Есть ли веская причина для другого порядка аргументов в функциях, получающих N-й элемент Array, List или Seq:
Array.get source index
List .nth source index
Seq .nth index source
Я хотел бы использовать оператор трубы, и это кажется возможным только с Seq:
s |> Seq.nth n
Есть ли способ иметь такую же запись с Array или List?
3 ответа
Я не думаю, что есть веская причина для определения Array.get
а также List.nth
сюда. Учитывая, что конвейерная обработка очень распространена в F#, они должны были быть определены так, чтобы source
аргумент пришел последним.
В случае List.nth
, это не сильно изменится, потому что вы можете использовать Seq.nth
и время сложность еще O(n)
где n
длина списка:
[1..100] |> Seq.nth 10
Это не очень хорошая идея, чтобы использовать Seq.nth
на массивах, потому что вы теряете произвольный доступ. Хранить O(1)
время работы Array.get
Вы можете определить:
[<RequireQualifiedAccess>]
module Array =
/// Get n-th element of an array in O(1) running time
let inline nth index source = Array.get source index
В общем, другой порядок аргументов может быть уменьшен с помощью flip
функция:
let inline flip f x y = f y x
Вы можете использовать его непосредственно над функциями выше:
[1..100] |> flip List.nth 10
[|1..100|] |> flip Array.get 10
Просто используйте оператор обратной трубы:
[1..1000] |> List.nth <| 42
Поскольку оба оператора остаются ассоциативными, x |> f <| y
анализируется как (x |> f) <| y
и это делает свое дело.
Оператор обратной трубы также полезен, если вы хотите удалить скобки: f (very long expression)
можно заменить на f <| very long expression
,
Так как Pad и bytebuster ответили на ваш последний вопрос, я сосредоточусь на части почему.
Это основано на моих текущих знаниях, а не на исторических фактах.
Так как F#, полученный из OCaml и OCaml, имеет Array и List, но не Seq, а F# использует |> для естественной конвейерной обработки и проверки типов, а в OCaml отсутствует оператор pipleline, авторы F# сделали переключение для Seq. Но очевидно, что для обратной совместимости с OCaml они не все переключали.