Сделать вывод для цикла в выражении вычисления последовательности
Почему эти работы
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 }
Ответ 1
В соответствии с спецификацией F # выражение последовательности может быть либо нормальным выражением вычисления (это тот случай, когда вы пишете 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
Есть много других коротких форм, которые были бы полезны на практике, но я предполагаю, что цель состоит в том, чтобы обеспечить специальный синтаксис только для этого, очень частого случая и в противном случае сохранить язык единообразным.
Ответ 2
Чтобы добавить более подробную информацию в ответ @Tomas, ваш первый и третий пример разрабатываются как:
let x = Seq.collect (fun i -> {yield i}) {1..10}
в то время как ваш второй пример переведен на:
let x = Seq.map (fun i -> i) {1..10}
Правила перевода упоминаются в разделе 6.3.11 в спецификации. В этом разделе вы также можете видеть, что F # обрабатывает полные циклы for (for...in...do и for...to...do) равномерно, но специальный синтаксис с -> применяется только к блоку for...in....
Нет проблем, поскольку вы всегда можете использовать for...in... для выражения for...to....