Это довольно сложно, потому что есть несколько вещей, которые F # делает неявно.
Во-первых, синтаксис ->
на самом деле является просто сокращением для do yield
, поэтому следующее переводится как:
[ for i in 0 .. 5 -> i ]
= [ for i in 0 .. 5 do yield i ]
Это объясняет, почему вы не можете сделать -> yield!
, потому что перевод приведет к:
[ for i in 0 .. 5 -> yield! [i * 4; i] ]
= [ for i in 0 .. 5 do yield (yield! [i * 4; i]) ]
Вы бы вложили yield!
внутрь yield
, что не имеет смысла.
Второй хитрый момент - это синтаксис с do
. Это недавнее изменение в F #, которое облегчает написание генераторов списков (это фантастика c для домен-специфических c языков, которые конструируют такие вещи, как HTML деревья) - компилятор неявно вставляет yield
, поэтому код переводится как :
[ for i in 0 .. 5 do i ]
= [ for i in 0 .. 5 do yield i ]
Интересно то, что это работает и с несколькими выходами:
[ for i in 0 .. 5 do
i
i*10 ]
= [ for i in 0 .. 5 do
yield i
yield i*10 ]
Это еще одно различие между ->
и do
. С ->
вы можете получить только одну вещь. С do
вы можете получить несколько вещей.
Я полагаю, что сейчас очень мало причин для использования ->
. Это было на языке до неявного yield
и поэтому было полезно в более ранних версиях F #. Возможно, вам это больше не нужно, когда do
упрощает задачу.