В clojure я хотел бы написать хвостовую рекурсивную функцию, которая запоминает свои промежуточныерезультаты для последующих звонки.
[EDIT: этот вопрос был переписан с использованием gcd
в качестве примера вместо factorial
.]
Запомненный gcd
(наибольший общий делитель) может быть реализовано следующим образом:
(def gcd (memoize (fn [a b]
(if (zero? b)
a
(recur b (mod a b))))
В этой реализации, промежуточныерезультаты не запоминаются для последующихвызовов. Например, для вычисления gcd(9,6)
в качестве промежуточного результата вызывается gcd(6,3)
. Однако gcd(6,3)
не сохраняется в кэше запоминаемой функции, потому что точка рекурсии recur
является анонимной функцией, которая не запоминается.
Следовательно, если после вызова gcd(9,6)
мы вызовем gcd(6,3)
мы не выиграем от мемоизации.
Единственным решением, о котором я могу думать, будет использование мирской рекурсии (явный вызов gcd
вместо recur
), но тогда мы не выиграем от оптимизации хвостового вызова.
Есть ли способ добиться того и другого:
F#
. Здесь я ищу ответ в clojure
.