简体   繁体   English

如何通过F#的Seq.cast避免“价值限制”错误?

[英]How does one avoid “Value restriction” errors with F#'s Seq.cast?

I see that Seq has a cast function from IEnumerable to Seq, but how do I get it to work? 我看到Seq有一个从IEnumerable到Seq的强制转换功能,但是如何让它工作呢?

open System.Text.RegularExpressions;;
let v = Regex.Match("abcd", "(ab)");;
Seq.cast (v.Captures);;

This produces, 这会产生,

error FS0030: Value restriction. 错误FS0030:值限制。 The value 'it' has been inferred to have generic type val it : seq<'_a> 值'it'被推断为具有泛型类型val: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. 将'it'定义为一个简单的数据项,使其成为具有显式参数的函数,或者,如果您不打算将其作为泛型,则添加类型注释。

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. 否则cast需要上下文来推断正确的返回类型,像有一个行本身没有这样的上下文类型推断使用。

(This line converts the non-generic IEnumerable into a generic IEnumerable<Match> aka seq<Match> .) (此行将非通用IEnumerable转换为通用IEnumerable<Match> aka seq<Match> 。)

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: Brian通过显式指定函数的type参数发布了如何执行此操作:

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). 另一个选项是使用类型注释 ,它可以放在任何F#表达式周围并指定表达式的类型 - 这样就可以提示编译器类型推理(通过说某些表达式具有特定类型)。 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. 如果以一种聪明的方式提供信息,编译器将能够确定Seq.cast的类型参数应该是什么。 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. 从所有选项中,我认为Brians(显式)和我的第二个(函数的返回类型)是那些最惯用的选项,但是,您可以选择任何您认为最具可读性的选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM