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))]))
Другие вопросы по тегам