無限に繰り返す要素の部分列を含む無限列を作成する必要があります。繰り返し要素を持つ無限列
[1; 2; 3; 4; 1; 2; 3; 4; 1; 2; 3; 4; ...]
だから私はこれを書いた:
let l = [1; 2; 3; 4]
let s = seq { while true do yield! l }
は、これを行うための標準的な方法(機能)はありますか?
無限に繰り返す要素の部分列を含む無限列を作成する必要があります。繰り返し要素を持つ無限列
[1; 2; 3; 4; 1; 2; 3; 4; 1; 2; 3; 4; ...]
だから私はこれを書いた:
let l = [1; 2; 3; 4]
let s = seq { while true do yield! l }
は、これを行うための標準的な方法(機能)はありますか?
私はあなたのアプローチがこのシナリオでは良いと思います。そこ繰り返しを実装するための組み込みの機能はありませんが、あなたは、多くの場合、シーケンスを繰り返す必要がある場合は、1を自分で定義し、Seq
モジュールで、それを利用できるようにすることができます。
module Seq =
let repeat items =
seq { while true do yield! items }
かのように、あなたがうまく、Seq.repeat [ 1 .. 4 ]
を書くことができますF#IntelliSenseは、Seq
モジュールとSeq
モジュールの両方の機能を1つのモジュールで定義されているかのように表示するため、標準のF#ライブラリ関数でした(repeat
)。
あなたの実装とは別に、再帰的シーケンス式を使用することもできます。これは、シーケンスを生成する際によく使用されるもう1つのパターンです。 (あなたは、単純な繰り返しのためにどのような状態を必要としませんが)while
を使用することで、機能再帰に比べていくつかの点で不可欠である:
let rec repeat items =
seq { yield! items
yield! repeat items }
このアプローチあなたが発生しながら、いくつかの状態を維持したいときよりよいです。たとえば、1 ..
のすべての数字を生成すると、while
を使用すると、可変状態が必要となるため、あまりうまくいかないでしょう。再帰を使用すると、あなたは同じことを書くことができますように:
let rec numbersFrom n =
seq { yield n
yield! numbersFrom (n + 1) }
私はこれにイディオムはないと思いますが、あなたが持っているものは大丈夫ですが、ここにいくつかの選択肢があります。
アレイにあなたのサブシーケンスを変更した場合、あなたはあなたが持っているものを使用して
let a = [|1; 2; 3; 4|]
let s = Seq.initInfinite (fun i -> a.[i % a.Length])
を行うことができ、あなたも
let l = [1; 2; 3; 4]
let s = Seq.initInfinite (fun _ -> l) |> Seq.concat
を行うことができますが、それは何の短いません。
これは、ヘルパーオブジェクトを作成することなく、(多かれ少なかれ)1ライナーとして実行します。
let s = seq { while true do
for i in 1 .. 4 -> i }
[1; 2; 3; 4]リストは一例にすぎません。実際には、シーケンスを構築するために必要なオブジェクトのリストがあります。 – Max
ダニエルの答えに似ていますが、機能にそれをカプセル化し、その機能をふりするのSeqモジュールである:
module Seq =
let infiniteOf repeatedList =
Seq.initInfinite (fun _ -> repeatedList)
|> Seq.concat
// Tests
let intList = [1; 2; 3; 4]
let charList = ['a'; 'b'; 'c'; 'd']
let objList = [(new System.Object()); (new System.Object()); (new System.Object()); (new System.Object())]
do
Seq.infiniteOf intList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item)
Seq.infiniteOf charList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item)
Seq.infiniteOf objList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item)
一つの落とし穴ここに: 'Seq.initInfinite'は、ある無限大の値に対して無限のシーケンスしか生成しません。 [documentation](http://msdn.microsoft.com/en-us/library/ee370429.aspx)から: "反復はInt32.MaxValueまで続けることができます。" –
これは、コアlibの無限の定義に適合します。これは使用可能な作業定義です。 – Daniel