F# 具有重复元素的无限序列

F# 具有重复元素的无限序列,f#,F#,我需要创建一个无限序列,其中包含无限重复的元素子序列 [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 } 有没有一种标准的方法(函数)来实现这一点?我认为没有专门的习惯用法,您所拥有的也不错,但这里有一些替代方法 如果将子序列更改为数组,则可以执行以下操作 let a = [|1; 2; 3; 4|] let s = Seq

我需要创建一个无限序列,其中包含无限重复的元素子序列

[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 }

有没有一种标准的方法(函数)来实现这一点?

我认为没有专门的习惯用法,您所拥有的也不错,但这里有一些替代方法

如果将子序列更改为数组,则可以执行以下操作

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
但它并不短。

这将作为一个(或多或少)一行程序来完成,而不必创建任何辅助对象

let s = seq { while true do
                for i in 1 .. 4 -> i }

我认为在这种情况下,您的方法很好。没有实现重复的内置函数,但是如果您需要经常重复序列,您可以自己定义一个,并在
Seq
模块中提供:

module Seq = 
  let repeat items = 
    seq { while true do yield! items }
然后您可以很好地编写
Seq.repeat[1..4]
,就好像
repeat
是一个标准的F#库函数一样,因为F#IntelliSense显示了
Seq
模块和
Seq
模块中的两个函数,就像它们是在单个模块中定义的一样

除了实现之外,还可以使用递归序列表达式,这是生成序列时另一种非常常见的模式。与函数递归相比,在某些方面使用
while
是必需的(尽管简单重复不需要任何状态):

let rec repeat items = 
  seq { yield! items  
        yield! repeat items }
当您希望在生成时保持某种状态时,这种方法会更好。例如,使用
while
生成所有数字
1..
就不太好了,因为您需要可变状态。使用递归,您可以编写与以下内容相同的内容:

let rec numbersFrom n = 
  seq { yield n
        yield! numbersFrom (n + 1) }

与Daniel的答案类似,但将其封装到函数中,并假装该函数位于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
只为无限的某些值生成无限序列。From:“迭代可以持续到Int32.MaxValue。”它符合核心库的无限定义,这是一个可用的工作定义。[1;2;3;4]列表只是一个示例。实际上,我有一个对象列表,我需要从中构造序列。