Решение упражнения 2.79 из SICP

26 February, 2008 (21:49) | Решения упражнений

Первым делом, определим саму обобщенную операцию проверки эквивалентности equ?. Мы еще не определяли обобщенных операций, являющихся предикатами. Но никаких сложностей с этим не возникает, ведь предикат – это всего лишь частный случай обыкновенной процедуры, который возвращает булево значение (истина или ложь). Таким образом определяется обобщенный предикат так же, как любая обобщенная операция:
(define (equ? x y) (apply-generic 'equ? x y))

Однако, есть важный нюанс. Поскольку возвращаемое значение имеет не пользовательский тип, а логический, нам не нужно добавлять к нему тег типа при определении в пакетах обыкновенных, рациональных и комплексных чисел.

Для того, чтобы реализовать equ? для каждого типа чисел, добавим в install-scheme-number-package следующий код:
(put 'equ? '(scheme-number scheme-number) =)

В install-rational-package аналогично добавим (процедура equal-rat? взята один в один из раздела 2.1.1 без модификаций):

(define (equal-rat? x y)
  (= (* (numer x) (denom y))
     (* (numer y) (denom x))))
(put 'equ? '(rational rational) equal-rat?)

В install-complex-package добавим такие строки:

(define (equal-complex? x y)
  (and (= (real-part x) (real-part y))
       (= (imag-part x) (imag-part y))))
(put 'equ? '(complex complex) equal-complex?)

Все. Теперь наша обобщенная операция equ? будет работать при сравнении пар обыкновенных, рациональных либо действительных чисел. Правда, сравнить обыкновенный 0 с рациональным 0/1 или комплексным 0+0i не получится. Пока что. Следующий раздел книги 2.5.2 как раз об этом…

Comments

Pingback from SICP по-русски » Решение упражнения 2.80 из SICP
Date: February 26, 2008, 10:58 pm

[…] упражнение аналогично предыдущему, поэтому буду краток, но остановлюсь на интересных […]

Write a comment