我正在尝试使用F#懒惰地创建一个序列。
序列定义如下:
序列的第n个术语 三角形数字由,tn =给出 ½n(N + 1);所以前十个三角形 数字是:
1,3,6,10,15,21,28,36,45,55, ...
这是我到目前为止所做的,但似乎无法发挥作用:
let tri_seq = 1.0 |> Seq.unfold (fun x -> match x with
| _ -> Some (x, 0.5*x*(x + 1.0)))
非常感谢谁能帮我弄清楚展开的效果。感谢
编辑:我将第一个答案标记为正确,但它确实有效,但是我稍微修改了它并且有效。
let tri_seq = 1.0 |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0),x + 1.0))
答案 0 :(得分:8)
首先,如果您只有一个案例,为什么要使用match
?
let tri_seq = 1.0 |> Seq.unfold (fun x -> Some (x, 0.5 * x * (x + 1.0)))
其次,什么“似乎不起作用”?你知道你产生了无限的名单吗?
/编辑:为了完整起见,这是正确的解决方案,OP发现自己并发布评论:
let tri_seq =
1.0 |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0), x + 1.0))
答案 1 :(得分:4)
Brian发布的代码的另一种替代方法是使用递归而不是命令式“while”循环:
let tri =
let rec loop(n, diff) = seq {
yield n
yield! loop(n + diff, diff + 1.0) }
loop(1.0, 2.0)
printfn "%A" (tri |> Seq.take 10 |> Seq.to_list)
效率低得多(所以你必须要小心一点......),但这是更惯用的功能解决方案,因此可能更容易看到代码的功能。
答案 2 :(得分:2)
这是另一种选择:
let tri = seq {
let n = ref 1.0
let diff = ref 2.0
while true do
yield !n
n := !n + !diff
diff := !diff + 1.0
}
printfn "%A" (tri |> Seq.take 10 |> Seq.to_list)
答案 3 :(得分:1)
我知道这是一个非常古老的,但是当你确定x *(x + 1)是偶数且可以被2整除时,我无法弄清楚为什么使用float。 所以我会简单地使用这一个(我知道的差别不大,但至少你有一个int seq):
let tri_seq = 1 |> Seq.unfold (fun x -> Some (x * (x + 1) / 2 , x + 1))
tri_seq |> Seq.take 6 |> Seq.toList //[1; 3; 6; 10; 15; 21]
(除非你处理大量的课程......)