web-dev-qa-db-ja.com

リストではなくF#でシーケンスを使用する場合

list には実際に値が含まれており、 sequenceIEnumerable<T>のエイリアスであることを理解しています。実際のF#開発では、リストではなくシーケンスをいつ使用する必要がありますか?

シーケンスの方が良い場合がある理由は次のとおりです。

  • IEnumerable<T>を必要とする他の.NET言語またはライブラリとやり取りする場合。
  • 無限のシーケンスを表す必要があります(おそらく実際にはあまり役に立ちません)。
  • 遅延評価が必要です。

他にありますか?

78
dodgy_coder

Seqをいつ選択するかについての要約はかなり良いと思います。追加のポイントは次のとおりです。

  • 関数の作成時には、デフォルトでSeqを使用します。これは、.NETコレクションで機能するためです。
  • Seq.windowedSeq.pairwiseなどの高度な機能が必要な場合は、Seqを使用してください

デフォルトでSeqを選択するのが最良の選択だと思います。そのため、いつ別のタイプを選択するのですか?

  • head::tailパターンを使用して再帰的な処理が必要な場合は、Listを使用します
    (標準ライブラリでは利用できない機能を実装するため)

  • 段階的に構築できる単純な不変のデータ構造が必要な場合は、Listを使用します
    (たとえば、ある統計を表示するために、あるスレッドでリストを処理する必要があり、同時にネットワークサービスからより多くの値を受信するときに別のスレッドでリストの構築を継続する必要がある場合)

  • 短いリストで作業する場合はListを使用してください。値が空のリストを表すことが多い場合は、listが最適なデータ構造です。このシナリオでは非常に効率的です。

  • 値型の大きなコレクションが必要な場合は、Arrayを使用します
    (配列はデータをフラットメモリブロックに格納するため、この場合はメモリ効率が向上します)

  • ランダムアクセスまたはより多くのパフォーマンス(およびキャッシュの局所性)が必要な場合は、Arrayを使用します

84
Tomas Petricek

また、次の場合はseqを優先します。

  • すべての要素を同時にメモリに保持する必要はありません。

  • パフォーマンスは重要ではありません。

  • 列挙の前後に何かをする必要があります。データベースに接続し、接続を閉じます。

  • 連結していません(繰り返しSeq.appendはスタックオーバーフローします)。

次の場合にlistを優先します。

  • いくつかの要素があります。

  • あなたは多くを前につけて首を切るでしょう。

seqlistも並列処理には適していませんが、必ずしもそれらが悪いことを意味するわけではありません。たとえば、どちらかを使用して、並行して行われる別個の作業項目の小さな束を表すことができます。

27
Jon Harrop

小さな点が1つだけあります:SeqArrayは、並列処理に関してListよりも優れています。

いくつかのオプションがあります: PSeq F#PowerPackから、 Array.Parallel モジュールおよび Async.Parallel (非同期計算)。リストはその逐次的な性質(head::tail構成)。

11
pad

リストはより機能的で数学にやさしいです。各要素が等しい場合、2つのリストは等しいです。

シーケンスではありません。

let list1 =  [1..3]
let list2 =  [1..3]
printfn "equal lists? %b" (list1=list2)

let seq1 = seq {1..3}
let seq2 = seq {1..3}
printfn "equal seqs? %b" (seq1=seq2)

enter image description here

7
Rm558

公開APIでは常にSeqを公開する必要があります。内部実装でListおよびArrayを使用します。

5