2010-06-07 3 views
2

Я вижу, что Seq имеет функцию трансляции от IEnumerable до Seq, но как мне заставить ее работать? FS0030Как избежать ошибок ограничения значения с помощью Seq.cast F #?

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

Это производит,

ошибки: ограничение Значения. Значение «it» было выведено, чтобы иметь общий тип val it: seq < '_a>
Либо определите' it 'как простой термин данных, сделайте его функцией с явными аргументами, либо, если вы этого не намерены чтобы быть общим, добавьте аннотацию типа.

ответ

8

Четко о типе:

Seq.cast<Match> (v.Captures) 

В противном случае cast необходим контекст, чтобы вывести правильный тип возвращаемого значения, а на линии само по себе, как там, нет такого контекста для вывода типа для использования.

(Эта линия преобразует необщий IEnumerable в общий IEnumerable<Match> А.К.А. seq<Match>.)

6

Есть фактически два способа указать тип, который вы хотите получить. Брайан писал, как сделать это, явно указав тип параметра в функции:

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

Другой вариант заключается в использовании аннотацию типа, которые могут быть размещены вокруг любого выражения F # и указать тип выражения - это вы можете намекнуть на inferrence типа компилятора (говоря, что какое-то выражение имеет определенный тип). Если вы предоставите информацию каким-то умным способом, компилятор сможет определить, какой должен быть параметр типа 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 (явный) и мое второе (типа возвращаемого значения функции) являются те, которые являются наиболее идиоматическим, однако, вы можете выбрать любой вариант вы найдете наиболее читаемым.