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

发布于 2024-09-05 09:36:20 字数 311 浏览 11 评论 0原文

我看到 Seq 有一个从 IEnumerable 到 Seq 的转换函数,但如何让它工作?

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

这会产生

错误 FS0030:值限制。值“it”已被推断为具有泛型类型 验证它:seq<'_a>
将“it”定义为简单的数据术语,使其成为具有显式参数的函数,或者,如果您不希望它是通用的,则添加类型注释。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何其悲哀 2024-09-12 09:36:20

明确类型:

Seq.cast<Match> (v.Captures)

否则 cast 需要上下文来推断正确的返回类型,并且在像这样的一行中,没有这样的上下文供类型推断使用。

(此行将非泛型 IEnumerable 转换为泛型 IEnumerable 又名 seq。)

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>.)

囍孤女 2024-09-12 09:36:20

实际上有两种方法可以指定您想要获取的类型。 Brian 发布了如何通过显式指定函数的类型参数来做到这一点:

let res = Seq.cast<Match> v.Captures

另一个选项是使用类型注释,它可以放置在任何 F# 表达式周围并指定表达式的类型 - 这样您就可以可以提示编译器类型推断(通过说某些表达式具有特定类型)。如果您以某种巧妙的方式提供信息,编译器将能够找出 Seq.cast 的类型参数应该是什么。举几个例子:

// 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
  // ...

从所有选项中,我认为 Brians(显式)和我的第二个(函数的返回类型)是最惯用的选项,但是,您可以选择您认为最具可读性的任何选项。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文