Seq.cast - F#
Lets examine Seq.cast.
Seq.cast: Wraps a loosely-typed System.Collections sequence as a typed sequence. ~ FSharp.Core
And also:
Seq.cast is useful when working with older parts of the BCL (base class library) that have specialized collection classes rather than generics. ~ fsharpforfunandprofit
Generics were not an original part of .NET/C#. They weren’t supported until C# 2.0. Seq.cast
is useful to convert older pregeneric collections into generic collections.
The F# docs have this example:
let unboxedExample =
[box 1; box 2; box 3]
[<EntryPoint>]
let main argv =
let intSeq =
unboxedExample
|> Seq.cast
printfn "%A" intSeq
0
Output: seq [1; 2; 3]
In F#, the box
and unbox
mechanisms allow primitive values (int
, double
, bool
, etc) to behave as objects. Primitives are stack based, objects are heap based.
The usage of Seq.cast
in this example “casts” that object value back into it’s primitive value.
I find the fsharpforfunandprofit example more revealing for it’s purpose. I’ve explicitly added the type of the matchCollection
.
let matches =
let pattern = "\d\d\d"
let matchCollection: MatchCollection = Regex.Matches("123 456 789",pattern)
matchCollection
|> Seq.cast<Match>
|> Seq.map (fun m -> m.Value)
|> Seq.toList
//ouputs = ["123"; "456"; "789"]
As you can see, Regex.Matches
returns a non helpful collection type, MatchCollection
. Having a seq
, list
or array
would be easier to work with.
If we first cast it to Match
, now we’re working with a seq<Match>
, and can use common library functions.
Notes:
- I can’t remember a time where I needed this functionality, in either my C# or F# experience. So not something I’d see myself using soon.
- If items in your collection can’t cast to your desired type, RuntimeException!! So be careful!