Ответ от @Carsten правильный: вы можете использовать Seq.toArray
или Seq.toList
, если хотите преобразовать лениво оцениваемые последовательности в списки или массивы. Однако не используйте эти функции для принудительной оценки.
Наиболее распространенная причина, по которой люди склонны спрашивать об этом, заключается в том, что у них есть прогноз, связанный с побочными эффектами, и они хотят навязать оценку. Возьмем этот пример, когда нужно вывести значения на консоль:
let lazySeq = seq { for i in 1 .. 10 do yield i * i }
let nothingHappens = lazySeq |> Seq.map (printfn "%i")
Проблема в том, что при оценке этих двух выражений ничего не происходит:
>
val lazySeq : seq<int>
val nothingHappens : seq<unit>
Поскольку nothingHappens
является ленивой вычисляемой последовательностью, никаких побочных эффектов от map
не возникает.
Люди часто прибегают к Seq.toList
или Seq.toArray
для принудительной оценки:
> nothingHappens |> Seq.toList;;
1
4
9
16
25
36
49
64
81
100
val it : unit list =
[null; null; null; null; null; null; null; null; null; null]
Хотя это работает, это не особенно идиоматично; он возвращает странный тип: unit list
.
Более идиоматичным решением является использование Seq.iter
:
> lazySeq |> Seq.iter (printfn "%i");;
1
4
9
16
25
36
49
64
81
100
val it : unit = ()
Как вы можете видеть, это вызывает принудительную оценку, но имеет более разумный тип возвращаемого значения unit
.
person
Mark Seemann
schedule
03.02.2016