История изменений
Исправление
dave,
(текущая версия)
:
Не может он являться хвостовым, так как его результат должен быть сначала вычислен, затем передан в >>
Распишу для F#. Для простоты изложения будем использовать явную монадическую связку, раз ленивость запутывает и уводит от сути:
let whileAsync p m =
if p () then
async.Bind(m, fun () -> whileAsync p m)
else
async.Zero()
Так стало понятнее?
Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.
Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!
Исправление
dave,
:
Не может он являться хвостовым, так как его результат должен быть сначала вычислен, затем передан в >>
Распишу для F#. Для простоты изложения будем использовать явную монадическую связку, раз ленивость запутывает и уводит от сути:
let whileAsync p m =
if p then
async.Bind(m, fun () -> whileAsync p m)
else
async.Zero()
Так стало понятнее?
Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.
Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!
Исправление
dave,
:
Не может он являться хвостовым, так как его результат должен быть сначала вычислен, затем передан в >>
Распишу для F#. Для простоты изложения будем использовать явную монадическую ссылку, раз ленивость запутывает и уводит от сути:
let whileAsync p m =
if p then
async.Bind(m, fun () -> whileAsync p m)
else
async.Zero()
Так стало понятнее?
Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.
Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!
Исправление
dave,
:
Не может он являться хвостовым, так как его результат должен быть сначала вычислен, затем передан в >>
Распишу для F#. Для простоты изложения будем использовать явную монадическую ссылку.
let whileAsync p m =
if p then
async.Bind(m, fun () -> whileAsync p m)
else
async.Zero()
Так стало понятнее?
Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.
Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!
Исходная версия
dave,
:
Не может он являться хвостовым, так как его результат должен быть сначала вычислен, затем передан в >>
Распишу для F#. Там от ленивости уходят, используя явную монадическую ссылку.
let whileAsync p m =
if p then
async.Bind(m, fun () -> whileAsync p m)
else
async.Zero()
Так стало понятнее?
Вызов хвостовой. Поскольку в Bind тоже вызовы все хвостовые (см. код F#), то созданы все условия для работы оптимизатора хвостового вызова.
Кстати, бесконечный цикл while true для async в F# в обычном .NET не сжирает всю память именно по этой причине!