скрывающиеся проблемы
Как заметил @Джон, вам нужно удалить ,
в (ini, f)
и изменить на (ini f)
.Это приводит к синтаксически правильной программе, но другие проблемы сохраняются.
Я бы порекомендовал внести изменения в вашу compose
процедуру.Во-первых, начальная '()
неверна, потому что она не соответствует типу функции.Вы получите странный результат, если попытаетесь применить аргумент к пустой композиции
(define (composex funcs)
(lambda (x)
(reducex '()
(lambda (ini f) (f x))
funcs)))
(define foo (composex '()))
(foo 'x) ; => '()
Во-вторых, ваш редуктор (lambda (ini f) (f x))
неверен, поэтому вы получаете неправильные ответы
(absmult2 2) ; 4
(absmult2 -2) ; -4
Это потому, что ваш редуктор игнорирует ini
.Это фактически то, что происходит, когда мы вызываем (absmult2 -2)
(let ((ini '()))
(set! ini (abst -2))
(set! ini (mult2 -2))
ini) ;; -4
На самом деле нам нужно поведение
(let ((ini -2))
(set! ini (abst ini))
(set! ini (mult2 ini))
ini) ;; 4
Мы можем исправить эти две проблемы одновременно, переработав composex
(define (composex funcs)
(lambda (ini)
(reducex ini
(lambda (x f) (f x))
funcs)))
(absmult2 2) ; 4
(absmult2 -2) ; 4
Теперь это работает и для пустых композиций
(define foo (composex '()))
(foo 'z) ; 'z
помогая себе
По иронии судьбы, ошибка, которую вы сделали изначально, может быть использованав другом месте, чтобы улучшить читаемость вашего кода.Вы можете использовать запятую без кавычек ,
вместо cons
, чтобы определить свою композицию.Обратите внимание на использование квазицитата `
(define absmult2 (composex `(,abst ,mult2)))
(absmult2 2) ; 4
(absmult2 -2) ; 4
В качестве альтернативы, вы можете изменить composex
, чтобы он принимал переменное количество входных данных
(define (composex . funcs)
(lambda (ini)
(reducex ini
(lambda (x f) (f x))
funcs)))
(define absmult2 (composex abst mult2))
(absmult2 2) ; 4
(absmult2 -2) ; 4
латеральное мышление
Рассмотрите эти другие реализации composex
как способ пощекотать ваш мозг
(define (composex . fs)
;; simplified composition of two functions
(define (comp f g)
(lambda (x) (g (f x))))
;; results in simplified reduce
(reducex identity comp fs))
(define absmult2 (composex abst mult2))
(absmult2 2) ; 4
(absmult2 -2) ; 4
Выше, как это composex
обрабатываетпустой пример композиции, о котором мы говорили?
А тот, который даже не использует reduce
- обратите внимание, что последний не позволяет программисту создать пустую композицию
(define (composex f . fs)
(lambda (x)
(if (null? fs)
(f x)
((apply composex fs) (f x)))))
(define absmult2 (composex abst mult2))
(absmult2 2) ; 4
(absmult2 -2) ; 4