В первом выражении вы выполняете вычисление, которое приводит к значению 1
, и все. Вам не нужен Zero
, потому что Zero
необходим только для return
безсловных выражений (поэтому он называется «ноль» - это то, что есть, когда ничего не существует), и ваше выражение имеет return
.
Чтобы ответить на ваш вопрос, Zero
не требуется «для инструкции printfn», потому что не каждая строка внутри выражения преобразуется. При компиляции выражений вычислений компилятор разбивает их на «специальные» точки, такие как let!
, do!
, return
и т. Д., Оставляя весь остальной код между этими точками неповрежденными. В этом случае ваш вызов printfn
просто становится частью кода, который выполняется до return
.
Во втором выражении, необходимо выполнить два вычисления: первое значение результатов в 1
и второй результаты в Zero
(которые неявно предполагается, когда выражение не имеет return
). Но все выражение вычисления не может иметь двух возвращаемых значений, оно должно иметь одно. Поэтому, чтобы свести результаты двух вычислений вместе (можно сказать, объединить их), вам нужен метод Combine
.
Кроме того, Combine
и Zero
, для этого вам также необходимо выполнить Delay
. Многоточечные (т. Е. «Комбинированные») вычисления также завернуты в Delay
, чтобы позволить строителю отложить оценку и, возможно, отбросить некоторые части в рамках реализации Combine
.
Я рекомендую прочитать this introduction Скоттом Улашиным, в частности part 3 about Delay
and Run
.