在序列计算表达式中产生for循环

时间:2012-04-18 09:06:10

标签: f# sequence

为什么这些工作

let x = seq { for i in 1 .. 10 do yield i }
let x = seq { for i in 1 .. 10 -> i }
let x = seq { for i = 1 to 10 do yield i }

但是这个没有?

let x = seq { for i = 1 to 10 -> i }

2 个答案:

答案 0 :(得分:12)

根据the F# specification,序列表达式可以是正常计算表达式(这是您编写do yield的情况),也可以是特定于序列表达式的简短形式:

seq { comp-expr }
seq { short-comp-expr }

comp-expr案例涵盖了您的第一个和最后一个工作示例。简短表单使用->,并且规范明确指出唯一允许的简短表单使用in关键字:

short-comp-expr :=
   for pat in expr-or-range-expr -> expr        -- yield result

还有许多其他简短形式在实践中很有用,但我想目标是为这一个提供一种特殊的语法,非常频繁,并保持语言统一。

答案 1 :(得分:4)

要向@ Tomas的答案添加更多细节,您的第一个和第三个示例将详细说明为:

let x = Seq.collect (fun i -> {yield i}) {1..10}

而你的第二个例子被翻译成:

let x = Seq.map (fun i -> i) {1..10}

Section 6.3.11 in the spec中提到了翻译规则。在该部分中,您还可以看到F#统一处理完整的for循环(for...in...dofor...to...do),但->的特殊语法应用于{{1}只阻止。

没有问题,因为您始终可以使用for...in...来表达for...in...