2

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

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

这产生,

错误 FS0030:值限制。值 'it' 已被推断为具有泛型类型 val it : seq<'_a>
将 'it' 定义为一个简单的数据项,使其成为具有显式参数的函数,或者,如果您不打算使其成为泛型,添加类型注释。

4

2 回答 2

8

明确说明类型:

Seq.cast<Match> (v.Captures)

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

(此行将非泛型IEnumerable转换为泛型IEnumerable<Match>aka seq<Match>。)

于 2010-06-07T22:53:47.137 回答
6

实际上有两种方法可以指定要获取的类型。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(显式)和我的第二个(函数的返回类型)是最惯用的选项,但是,您可以选择任何您认为最易读的选项。

于 2010-06-08T01:25:53.777 回答