Array、List、または Seq の N 番目の要素を取得する関数で引数の順序が異なる理由はありますか。
Array.get source index
List .nth source index
Seq .nth index source
パイプ演算子を使用したいのですが、Seq でのみ可能のようです:
s |> Seq.nth n
Array や List で同じ表記にする方法はありますか?
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 が最後の質問に答えたので、理由の部分に焦点を当てます。
これは私の現在の知識に基づいており、歴史的事実ではありません。
OCaml と OCaml から派生した F# にはArrayとListがありますがSeq はなく、F# は自然なパイプライン処理と型チェックに |> を使用し、OCaml にはパイプライン演算子がないため、F# の作成者は Seq に切り替えました。しかし明らかに、OCaml との下位互換性を維持するために、すべてを切り替えたわけではありません。