Функциональное программирование




Внутреннее представление списков. Применяющие функционалы - часть 5


8

(defun countatom (lis)

(cond ((null lis) 0)

((atom lis) 1)

(t (apply '+ (mapcar 'countatom lis)))))


8.4.2 Cочетание apply, nconc, mapcar - mapcan.

Построить функцию list-last, образующую список из хвостов списков.

Например

* (list-last '((a b) (b c) (c d))) возвращает (b c d)

(defun list-last (lis)

(apply 'append (mapcar 'last lis)))

APPEND работает медленно и оставляет много мусора.

Можно это сделать через nconc:

(defun list-last (lis)

(apply 'nconc (mapcar 'last lis)))

В лиспе имеется отображающий функционал mapcan

(mapcan fn x1 x2 ... xN)

(apply 'nconc (mapcar fn x1 x2 ... xN))

T.е. mapcan объединяет результаты в один список, используя функцию nconc.

(defun list-last (lis)

(mapcan 'last lis))


8.4.3 Функционал FUNCALL.

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

аналогичен APPLY, но аргументы он

принимает, не в списке, а по отдельности:

(funcall fn x1 x2 ... xN) (fn x1 x2 ... xN)

Здесь fn - функция с n aргументами.

Например,

* (funcall '+ 1 2) * (+ 1 2)

3

* (funcall (car '(+ - / *)) 1 2)

3

Пример.

Рассмотрим использование funcall для построения функции map2, которая действует аналогично mapcar, но берет в качестве аргументов два элемента из списка, а не один.

Например:

* (map2 'list '(A Christie V Nabokov K Vonnegut))

дает ((A Christie) (V Nabokov) (K Vonnegut))

Эта функция имеет вид:

(defun map2 (f2 lst)

(if (null lst)

nil

(cons (funcall f2 (car lst) (cadr lst))

(map2 f2 (cddr lst)))))





Содержание  Назад  Вперед