A simple question but I think too longer

Hi, excuse me, how do I eliminate the seq expression with only Seq.xxxx in the next code block?

let test () =
let rec ttc c =
seq{
yield c
yield! (ttc <| c + 1I)
}
ttc 0I

let y = test ()

y |> Seq.take 5 |> Seq.map (fun bi → int bi)

Do you mean replace ttc to built-in function from Seq module? If so, take a look to the Seq.unfold

Seq.unfold (fun state -> Some(state, state + 1I)) 0I
2 Likes

Thanks so much!
By the way, is it possible not to use mutable variable/ref/expression builder to achieve unfold in a simple way?
(ref…
https://github.com/fsharp/fsharp/blob/6819e1c769269edefcea2263c98f993e90b623e2/src/fsharp/FSharp.Core/seq.fs)

      let unfold f x : IEnumerator<_> =
      let state = ref x
      upcast
          {  new MapEnumerator<_>() with
                member this.DoMoveNext curr =
                    match f !state with
                    |   None -> false
                    |   Some(r,s) ->
                            curr <- r
                            state := s
                            true
                member this.Dispose() = ()
          }
1 Like

It is possible, unfold can be implemented as recursive function:

let rec unfold f state =
    match f state with
    | Some (y, state2) -> Seq.append (Seq.singleton y) (Seq.delay (fun () -> unfold f state2))
    | None -> Seq.empty

(Note use of Seq.delay, without it we got infinite loop.)

Mutable in Seq.unfold is used for performance reasons to avoid unnecessary allocations.

2 Likes

This is so so so cool!! Marvelous!!
Thank you so much!!

Now I got my test without seq expression…

let test () =
    let rec ttc c = 
        Seq.append (seq[c]) (Seq.delay (fun () -> ttc (c + 1)))
    ttc 0

let y = test ()
y |> Seq.item 5