Recursive Sequence Expressions in F#
One nice feature of F# is sequence expressions which let you write code that emits a sequence (think IEnumerable<T>
if you are a C# developer). Within a sequence expression you can use the yield
operator to emit values in the sequence much like you can in C#:
let x = seq {
yield "Hello"
yield "World"
}
You can also use the yield!
operator to emit all the values from another sequence one by one. So the following code would create a four element sequence:
let x = seq {
yield "Hello"
yield "World"
yield! ["foo"; "bar"]
}
The yield!
operator also opens up the possibility of creating a recursive sequence. So you can do something like this and create a never-ending sequence:
let rec x = seq {
yield "Hello"
yield "World"
yield! ["foo"; "bar"]
yield! x
}
But obviously you are likely to want to terminate your sequence at some point, and so you need an equivalent of C#’s yield break
. It took me a while to work out how to do this in F#, but eventually I realised it was as simple as returning “unit” which is expressed in F# as ()
. To illustrate how to use it, I’ve created a simple “countdown” function using a recursive sequence:
let rec countdown from =
seq {
match from with
| 0 -> ()
| n ->
yield n
yield! countdown (from - 1)
}
Obviously that’s not the best way to implement a countdown sequence in F#. That can be done much more elegantly using another form of sequence expressions:
seq { 10 .. -1 .. 1 }
But hopefully this post helps any C# developers wondering how they can do a yield break
in F#.
Comments
Thank you for sharing, exactly what I was looking for :)
Paweł IżyckiYou could use
Shimmer66Seq.takeWhile (fun n -> n > 0)
instead of matching on 0.