Разный порядок аргументов для получения N-го элемента массива, списка или Seq
Есть ли веская причина для другого порядка аргументов в функциях, получающих N-й элемент массива, списка или Seq:
Array.get source index
List .nth source index
Seq .nth index source
Я хотел бы использовать оператор трубы, и это кажется возможным только с Seq:
s |> Seq.nth n
Есть ли способ иметь одно и то же обозначение с массивом или списком?
Ответы
Ответ 1
Я не думаю о какой-либо хорошей причине для определения 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
Ответ 2
Просто используйте оператор обратной трубы:
[1..1000] |> List.nth <| 42
Поскольку оба оператора оставлены ассоциативными, x |> f <| y
анализируется как (x |> f) <| y
, и это делает трюк.
Оператор обратной линии также полезен, если вы хотите удалить круглые скобки: f (very long expression)
можно заменить на f <| very long expression
.
Ответ 3
Так как Pad и bytebuster ответили на ваш последний вопрос, я сосредоточусь на том, почему.
Это основано на моих текущих знаниях, а не на исторических фактах.
Так как F #, полученный из OCaml и OCaml, имеет Array и List, но not Seq и F # использует | > для естественной конвейерной обработки и проверка типов и В OCaml отсутствует оператор pipleline, авторы F # сделали переключатель для Seq. Но, очевидно, чтобы быть обратно скомпонованными с OCaml, они не переключили все.