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

Применяющие функционалы

К применяющим функционалам относятся – apply и funcall. Различие их использования заключается в том, что apply должен получить 2 аргумента - функцию и список. Список содержит аргументы для выполнения аппликации функции. Функционал funcall получает в вызове произвольное число аргументов. Первый аргумент трактуется как функция, а остальные аргументы используются для выполнения аппликации функции.

Примеры

(apply ‘+ ‘(2 3)) -> 5

(apply ‘cons ‘(1 (2 3)) -> (1 2 3)

(setq f ‘+) -> +; присваивание f значения – символа +

(apply f ‘(2 3)) -> 5

(apply ‘eval ‘(+ 2 3)) -> 5

(apply ‘apply ‘(+ (2 3))) - > 5 ; для apply подготовлено 2 аргумента – символ + и

; список (2 3)

(apply ‘(lambda (x y) (+ x y)) ‘(2 3)) -> 5

(apply (lambda (x y) (+ x y)) ‘(2 3)) -> 5

(apply + ‘(2 3)) -> !Ошибка

(setq ff ‘(lambda (x y) (+ x y))) -> (lambda (x y) (+ x y))

(apply ff ‘(2 3)) -> 5

(funcall ‘+ 2 3) -> 5

(funcall f 2 3) -> 5

(funcall cons 2 ‘(3)) -> !Ошибка, т.к. делается попытка найти для символа cons

значение в текущем контексте вычислений, а cons ни с чем

не связано

(funcall ‘cons 2 ‘(3)) -> (2 3)

Пример

Определение функционала f2f, реализующего композицию 2-х функций.

(defun f2f(f g x)(funcall f (funcall g x))) -> f2f

(defun f1(x)(+ x x)) -> f1

(defun f2(x)(* x x)) -> f2

(f2f ‘f1 ‘f2 2) -> 8

(f2f f1 f2 2) -> !Ошибка, попытка найти значения f1и f2 в контексте переменных

Отображающие функционалы

Отображающие функционалы являются функциями, которые повторно применяют функцию аргумент к элементам списка и тем или иным способом формируют список-результат. В любую реализацию Лиспа входит довольно обширный набор отображающих функционалов (обычно порядка 10-12). Аппликация отображающего функционала выглядит следующим образом:

(mapИмя fn l),

где Имя – имя конкретного функционала, сопровождаемое префиксом map, fn – применяемая функция, l – список элементов, подлежащих обработке.

Функционалы mapcar и maplist выполняют следующее. Первый из них применяет функцию последовательно к элементам списка. Каждый полученный результат аппликации функции связывается в список в той же последовательности, что и исходные аргументы. Функционал maplist повторяет вычисления на хвостовых элементах списка.

Пример

(mapcar ‘atom ‘(a b c)) -> (t t t)

(maplist ‘atom ‘(a b c)) -> ( nil nil nil)

(maplist ‘reverse ‘(a b c)) -> ((c b a)(c b)(c))

Вызовы функционалов можно объединять в более сложные структуры управления вычислениями точно таким же образом, как и обычные функции.

Пример

Декартово произведение 2-х множеств можно выразить через композицию вложенных вызовов функционала mapcar, подобно вычислению через 2 вложенных цикла:

(defun decart(x y)

(mapcar ‘(lambda (x)

(mapcar ‘(lambda (y) (list x y))

y))

x))

Последовательность вычислений в процессе вызова функции decart следующая. Внешний вызов mapcar применяет свою функцию-аргумент последовательно к элементам списка (a b c), а вложенный вызов – к элементам списка (1 2 3). Таким образом, в теле этого «двойного цикла» вначале вычисляется выражение (mapcar ‘(lambda (y) (list ‘a y)) ‘(1 2 3)), затем (mapcar ‘(lambda (y) (list ‘b y)) ‘(1 2 3)) и, наконец (mapcar ‘(lambda (y) (list ‘с y)) ‘(1 2 3)). Таким образом, конечный результат будет таким:

( ((a 1) (a 2) (a 3))( (b 1) (b 2) (b 3))( (c 1) (c 2) (c 3) ))

Пример

(defun plus (lst)

(if (eq lst nil) 0

(if (eq (length lst) 1) (car lst)

(+ (car lst) (plus (cdr lst)))

)

)

) -> plus

(maplist ‘plus ‘(1 2 3 4)) -> (10 9 7 4)

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