Reputation: 16850
I see that Seq has a cast function from IEnumerable to Seq, but how do I get it to work?
open System.Text.RegularExpressions;;
let v = Regex.Match("abcd", "(ab)");;
Seq.cast (v.Captures);;
This produces,
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : seq<'_a>
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
Upvotes: 2
Views: 687
Reputation: 243061
There are actually two ways to specify the type you want to get. Brian posted how to do this by explicitly specifying the type parameter to a function:
let res = Seq.cast<Match> v.Captures
The other option is to use type annotations which can be placed around any F# expression and specify the type of the expression - this way you can hint the compiler type inferrence (by saying that some expression has a particular type). If you provide the information in some clever way, the compiler will be able to figure out what the type parameter to Seq.cast
should be. A few examples:
// By specifying type of the value
let (res:seq<Match>) = Seq.cast v.Captures
// By specifying return type of a function
let getCaptures () : seq<Match> =
// ...
Seq.cast v.Captures
// By specifying element type when iterating over the result
for (m:Match) in Seq.cast v.Captures do
// ...
From all of the options, I think that the Brians (explicit) and my second (return type of a function) are those that are the most idiomatic, however, you can choose any option you find the most readable.
Upvotes: 6
Reputation: 118865
Be explicit about the type:
Seq.cast<Match> (v.Captures)
Otherwise cast
needs context to infer the right return type, and on a line by itself like there, there is no such context for type inference to use.
(This line converts the non-generic IEnumerable
into a generic IEnumerable<Match>
a.k.a. seq<Match>
.)
Upvotes: 8