Рекурсивный вызов traceColorAt
появляется как часть большего выражения. Это предотвращает оптимизацию хвостового вызова, потому что дальнейшие вычисления необходимы после возврата traceColorAt
.
Чтобы преобразовать эту функцию в хвостовую рекурсию, вы можете добавить дополнительный параметр аккумулятора для primaryColor
. Самый внешний вызов traceColorAt
передал бы значение "ноль" для primaryColor
(черный?), И каждый рекурсивный вызов суммируется в вычислении, которое он вычисляет, например, код будет выглядеть примерно так:
let rec traceColorAt intersection ray currentReflection primaryColor
...
let newPrimaryColor = primaryColor + ambient + diffuse + specular
...
match intersections with
| [] -> newPrimaryColor
| _ ->
...
traceColorAt newIntersection newRay ((currentReflection - 1) * reflectivity) newPrimaryColor
Если вы хотите скрыть дополнительный параметр от вызывающих, введите вспомогательную функцию, выполняющую основную часть работы, и вызовите ее из traceColorAt
.