Скачиваний:
8
Добавлен:
01.05.2014
Размер:
6.87 Кб
Скачать

Шаг 23. Отображающие функционалы. Функция MAPCAR     На этом шаге мы рассмотрим функцию MAPCAR.

    Рассмотрим вначале две функции.     Пример 1. (DEFUN SUMADD (LAMBDA (LST) % Функция, преобразующая список целых чисел в список, % % каждый из элементов которого на единицу больше % % соответствующего элемента % ( (NULL LST) NIL ) ( CONS (PLUS 1 (CAR LST)) (SUMADD (CDR LST)) ) )) % ------------------------ % (DEFUN TANUSHA (LAMBDA (LST) % Функция, преобразующая список целых чисел в список, % % каждый из элементов которого представляет собой ос- % % таток от деления соответствующего элемента на 2 % ( (NULL LST) NIL ) ( CONS (REMAINDER (CAR LST) 2) (TANUSHA (CDR LST)) ) ))     Очевидно, что есть нечто общее в структуре данных функций.     Возникает естественный вопрос: возможно ли обобщение?     Ниже мы построим функцию MAPCAR для диалекта muLISP81, с помощью которой вторая интересующая нас проблема решается так: $ (MAPCAR REMAINDER (2 4 6)) (0 0 0)     Обращение к функции MAPCAR выглядит следующим образом: (MAPCAR FN (X1 X2 ... XN))     Значение функции MAPCAR вычисляется путем применения функции FN к последовательным элементам Xi списка, являющегося вторым аргументом MAPCAR.     В качестве значения функционала возвращается список, построенный из результатов вызовов функционального аргумента MAPCAR.     Код функции для muLISP81 достаточно прост: (DEFUN MAPCAR (LAMBDA (FUN LST) (COND ( (NULL LST) NIL ) ( CONS (FUN (CAR LST)) (MAPCAR FUN (CDR LST)) ) ) ))     Отметим здесь, что вычисление функционала MAPCAR может быть осуществлено параллельно и не зависит от порядка обработки элементов списка.     Пример 2. $ (MAPCAR ATOM (A B C)) (T T T) $ (MAPCAR (LAMBDA (Y) (LIST (PRINT Y))) (A B C)) A B C ((A) (B) (C)) $ (PUTD PARA1 (LAMBDA (X) (LIST X 1))) PARA1 $ (MAPCAR PARA1 X) ((A 1) (B 1) (C 1)) $ (MAPCAR NUMBERP (1 2 МИМО 3)) (T T NIL T)     Пример 3. Дан список, содержащий целые положительные числа. Построить функцию, возвращающую список, состоящий из факториалов каждого элемента исходного списка. (DEFUN DEMO (LAMBDA (FUN LST) (PRIN1 "Результат действия MAPCAR: ") (MAPCAR FUN LST) )) % ------------------- % (DEFUN FACT (LAMBDA (X) (COND ( (ZEROP X) 1 ) ( T (TIMES X (FACT (DIFFERENCE X 1))) ) ) )) % --------------------------- % (DEFUN MAPCAR (LAMBDA (FUN LST) (COND ( (NULL LST) NIL ) ( T (CONS (FUN (CAR LST)) (MAPCAR FUN (CDR LST))) ) ) )) Тестовый пример: $ (DEMO FACT (2 3 4)) (2 6 24)     Пример 4. Прямое произведение двух числовых множеств можно определить через два вложенных цикла, которые можно выразить с помощью композиции двух вложенных вызовов функционала MAPCAR: (DEFUN DECART (LAMBDA (X Y) % X и Y - списки % (MAPCAR (QUOTE (LAMBDA (X) (MAPCAR (QUOTE (LAMBDA (Y) (LIST X Y))) Y))) X) )) % --------------------------- % (DEFUN MAPCAR (LAMBDA (FUN LST) (COND ( (NULL LST) NIL ) ( T (CONS (FUN (CAR LST)) (MAPCAR FUN (CDR LST))) ) ) )) Тестовый пример: $ (DECART (A B C) (1 2 3)) (((A 1) (A 2) (A 3)) ((B 1) (B 2) (B 3)) ((C 1) (C 2) (C 3)))     Замечание 1. Заметим, что обращение к функции MAPCAR следующим образом: (MAPCAR FN (X1 X2 ... XN)) эквивалентно обращению к функции LIST: (LIST (FN X1) (FN X2) ... (FN XN))     Замечание 2. Функция (MAPCAR FN LIST1...LISTN) выполняет действия, предписанные функцией FN, над CAR-элементами списков LIST1,...,LISTN, затем - над CADR-элементами каждого списка, и т.д. до тех пор, пока каждый список не будет исчерпан. Функция MAPCAR возвращает список результатов. Например: $ (MAPCAR '*'(2 3 5 7) '(2 4 6 8)) (4 12 30 56) Код функции в системе muLISP85 имеет вид: (DEFUN MAPCAR (FUNC LST1 LST2) ( (OR (NULL LST1) (NULL LST2)) NIL ) (CONS (FUNCALL FUNC (CAR LST1) (CAR LST2)) (MAPCAR FUNC (CDR LST1) (CDR LST2))) )

    На следующем шаге мы продолжим изучение отображающих функционалов, в частности, рассмотрим функцию MAPLIST.

Предыдущий шаг Содержание Следующий шаг

Соседние файлы в папке Язык программирования ЛИСП