Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Seq.unfold explanation in F#

Tags:

f#

seq.unfold

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))
like image 491
masfenix Avatar asked Dec 07 '22 08:12

masfenix


2 Answers

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))
like image 103
Konrad Rudolph Avatar answered Dec 20 '22 14:12

Konrad Rudolph


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.

like image 40
Tomas Petricek Avatar answered Dec 20 '22 13:12

Tomas Petricek