Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fp_6.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
477.18 Кб
Скачать

6.1.3 Функциональный тип данных

Вернёмся к вопросу о «типе данных».

Когда мы реализовывали арифметику рациональных чисел, всё, что мы о них знали, это то, что они создаются функцией make-rat из пары целых чисел, и что для любого рационального числа можно получить его числитель и знаменатель функциями числитель и знаменатель.

При этом, для любых целых чисел n и m должно выполняться следующее условие.

(числитель (make-rat n m))/(знаменатель (make-rat n m)) =  

Это единственное условие, которое накладывается на make-rat, числитель и знаменатель, и получается, что любые три функции ему удовлетворяющие могут быть использованы для осуществления рациональных чисел.

Мы можем рассматривать тип данных как некоторый набор конструкторов и селекторов вместе с определёнными условиями, которым эти функции должны удовлетворять.

6.1.4 Третье внутреннее представление рациональных чисел

Теперь рассмотрим точечную пару с функциональной точки зрения представления данных.

Единственное “условие пары”, которому должны удовлетворять операции, работающие с ними, т.е. cons, car и cdr состоит в том, что для любых объектов x и y должно выполнятся:

(car (cons x y)) = x и

(cdr (cons x y)) = y

Получается, что любая тройка функций, удовлетворяющих этому условию, может быть использоваться для создания пар. Отсюда следует, что мы можем реализовать, cons, car и cdr вообще не связывая эти функции с понятием точечной пары! И, как вывод, можно обойтись без структур данных!

Например, создать такие функции.

> (define (cons_n x y) (lambda (a) (if a x y)))

Получается, что рациональное число – это функция с определенными заранее двумя выходами, а какой из них нам нужен определяется единственным параметром при вызове.

> (define (car_n z) (z #t))

> (define (cdr_n z) (z #f))

В качестве единственного параметра z, должна выступать определённая выше – функция с заданными x и y.

Е

Например, будет так:

((cons_n 1 2) #t) ==> 1

((cons_n 1 2) #f) ==> 2

сли мы вызовем эту функцию с параметром #t – выберем первый выход, т.е первую часть числа (числитель), а если #f – второй.

Наше новое «функциональное» представление пар ничем не хуже любого другого, и если мы будем оперировать только посредством функций числитель и знаменатель, мы не сможем отличить это представление от того, которое использует какие-либо другие, скажем, «настоящие» структуры данных.

> (define (make-rat n d) (cons_n n d))

> (define (числитель r) (car_n r))

> (define (знаменатель r) (cdr_n r))

> (define r1 (make-rat 1 2))

Здесь получается, что r1 внутренне представляется так:

(lambda (a) (if a 1 2))

> (define r2 (make-rat 1 3))

> (define r3 (add-rat r1 r2))

И это – правильно!

> r3

#<procedure:48:22>

> (display-rat (sub-rat r3 r2))

=9/18

> (display-rat r1)

=1/2

Единственная неприятность, проистекающая из-за того, что результатом cons_n является функция, заключается в неотвратимости созерцать название получаемого представления, т.е. новой функции, например, #<procedure:1:22>, а не само число.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]