tags:

views:

819

answers:

3

Hi, 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)))

Thankyou 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))
+4  A: 

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))
Konrad Rudolph
I tried that, but the sequence just returns one..> tri_seq;;val it : seq<float> = seq [1.0; 1.0; 1.0; 1.0; ...]
masfenix
let tri_seq = 1.0 |> Seq.unfold (fun x -> Some (0.5 * x * (x + 1.0),x + 1.0)) is what i needed. Thankyou very much.
masfenix
+2  A: 

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)
Brian
+3  A: 

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.

Tomas Petricek
Thankyou, but i have no idea what the "Seq { }" does, not "yield" keyword, and lets not talk about the "!". If you can take some time to explain, it would be appreciated!
masfenix
Not an expert, but Seq {} means make me a sequence out of this. yield is same as C# - means send back value and wait for calling code to ask for next. yield! is (I believe) like Seq.concat - flattens the seq returned from recursive call and does a yield on each element.
Benjol