F# 中的 Seq.unfold 解释

发布于 2024-07-13 09:34:02 字数 653 浏览 8 评论 0原文

我正在尝试使用 F# 懒惰地创建一个序列。

该序列定义如下:

序列的第n项 三角形数由下式给出: tn = 1/2n(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))

I am trying to create a sequence lazily by using F#.

The sequence is defined as follows:

The nth term of the sequence of
triangle numbers is given by, tn =
½n(n+1); so the first ten triangle
numbers are:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55,
...

Here is what I have so far but it dosn't seem to work:

let tri_seq = 1.0 |> Seq.unfold (fun x -> match x with                                         
                                          | _ -> Some (x, 0.5*x*(x + 1.0)))

Thank you very much who can help me figure out how unfold works. Thanks

Edit: I marked the first answer as correct but it dosnt work, however I slightly modified it and it worked.

let tri_seq = 1.0 |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0),x + 1.0))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

余生一个溪 2024-07-20 09:34:02

首先,如果你只有一种情况,为什么要使用 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))

First off, why do you use match if you've got only one case?

let tri_seq = 1.0 |> Seq.unfold (fun x -> Some (x, 0.5 * x * (x + 1.0)))

Second, what “doesn't seem to work”? Are you aware that you produce an infinite list?

/Edit: For completeness’ sake, here’s the correct solution, which the OP found himself and posted as a comment:

let tri_seq = 
    1.0 |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0), x + 1.0))
吻安 2024-07-20 09:34:02

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)

它的效率要低得多(所以你必须在这里小心一点......),但它是更惯用的功能解决方案,所以它可能更容易看出代码的作用。

Another alternative to the code that Brian posted is to use recursion instead of imperative 'while' loop:

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)

It is far less efficient (so you have to be a bit careful here...), but it is more idiomatic functional solution, so it may be easier to see what the code does.

糖果控 2024-07-20 09:34:02

这是一个替代方案:

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)

Here is an alternative:

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)
夕嗳→ 2024-07-20 09:34:02

我知道这是一个相当老的问题,但是当你确定 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]

fiddle

(当然,除非你处理大量的数据......)

I know this is a pretty old one, but i cant figure out why using float when you are sure that x * (x + 1) is an even number and indeed divisible by 2.
So I would simply use this one instead (not much difference i know but at least you have an 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]

fiddle

(Unless you dealing with huge numbers of course....)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文