Corecursion не заканчивается после небольшого изменения
Я написал в Racket функцию для создания чего-то похожего на следующий фрактал.
(define CUT-OFF 5)
(define CIRCLE-MODE "outline")
(define (circle-fractal size colour)
(local [(define full-circle (circle size CIRCLE-MODE colour))]
(cond [(<= size CUT-OFF) full-circle]
[else
(overlay/align "middle" "middle"
full-circle
(beside (circle-fractal (/ size 2) colour)
(circle-fractal (/ size 2) colour)))])))
Это проходит мои тесты.
Я изменил код, думая, что ниже будет более читабельным.
(define (circle-fractal size colour)
(local [(define full-circle (circle size CIRCLE-MODE colour))
(define half-circle (circle-fractal (/ size 2) colour))]
(cond [(<= size CUT-OFF) full-circle]
[else
(overlay/align "middle" "middle"
full-circle
(beside half-circle half-circle))])))
Теперь функция не завершается. Ракетка достигает предела памяти без вывода.
Разве каждый вызов corecursive как-то не подходит к тривиальному случаю после этого изменения?
1 ответ
Решение
В первой версии (circle-fractal (/ size 2) colour)
оценивается только если size > CUT-OFF
, Во втором он называется независимо от размера. Таким образом, вы потеряли свой базовый случай рекурсии.
Пытаться:
(define (circle-fractal size colour)
(define full-circle (circle size CIRCLE-MODE colour))
(cond [(<= size CUT-OFF) full-circle]
[else
(define half-circle (circle-fractal (/ size 2) colour))
(overlay/align "middle" "middle"
full-circle
(beside half-circle half-circle))]))