Существует ли типичное имя для функции, такой как map, которая работает со списком аргументов вместо нескольких списков аргументов? - PullRequest
7 голосов
/ 24 января 2010

(я наконец-то написал и принял ответ на вопрос «нет, нет, и вопрос на самом деле не такой общий».)

Рассмотрим функцию Common Lisp 'mapcar'. Он принимает функцию и некоторые списки в качестве аргументов и вызывает функцию с аргументами, взятыми из одной и той же позиции в каждом списке.

Есть ли в стандартных библиотеках аналогичная функция, которая принимает один список, где каждый элемент списка представляет собой список аргументов для функции? Какую функцию обычно называют «стандартной» или нет? (Это не вопрос Lisp, но это единственный функциональный язык + библиотека, которую я знаю на полпути.)

Полагаю, я спрашиваю, как операция (в псевдо-Лиспе):

(mapcar (curry #'apply function-to-map) list-of-arg-lists)

уже имеет имя, которое является общим для нескольких языков или библиотек (точно так же, как «map» и «Reduce» являются именами для общих операций, а не только для определенных библиотечных функций).

Спасибо.

Ответы [ 3 ]

3 голосов
/ 25 января 2010

Я назначаю map-apply или, может быть, mapply, если вы хотите использовать его самостоятельно или в небольшой группе.

(defun map-apply (fn arg-lists)
    (mapcar (lambda (arg-list) (apply fn arg-list))
            arg-lists))

(map-apply #'+ '((1 2) (3 4 5)))
  =>
(3 12)

РЕДАКТИРОВАТЬ Конечно, вы не просто псевдо-Лисп, если у вас есть curry:

(defun curry (f &rest values)
    (lambda (&rest more-values)
        (apply f (append values more-values))))
1 голос
/ 01 февраля 2010

Рассмотрим функцию Common Lisp 'mapcar'. Он принимает функцию и некоторые списки в качестве аргументов и вызывает функцию с аргументами, взятыми из одной и той же позиции в каждом списке.

Есть ли в стандартных библиотеках аналогичная функция, которая принимает один список, где каждый элемент списка представляет собой список аргументов для функции?

Что ж, Haskell определяет ряд zipWithN -функций, которые имеют эффекты, аналогичные mapcar для постоянного числа аргументов.

zipWith (\a b -> a + b) [1, 2, 3] [1, 2, 3]                   => [2, 4, 6]
zipWith3 (\a b c -> a + b + c) [1, 2, 3] [1, 2, 3] [4, 5, 6]  => [6, 9, 12]

Обобщение этой концепции для списка списков приведет к этой (наивно реализованной) функции zipWithMany

zipWithMany :: ([a] -> b) -> [[a]] -> [b]
zipWithMany f lists 
    | any null lists = []
    | otherwise      = (f $ map head lists) : zipWithMany f (map tail lists)

Пример:

zipWithMany sum [[1, 2, 3], [1, 2, 3], [1, 2]] => [3, 6]
1 голос
/ 01 февраля 2010

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

Не каждый язык работает таким образом. Например, функции Haskell принимают только один типизированный аргумент (см. Другие ответы и комментарии и http://www.haskell.org/tutorial/index.html). Отображение функции, которая принимает тип кортежа в списке такого типа, концептуально аналогично операции, о которой я спрашивал, и в этом случае соответствующей функцией является ... 'map'.

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

Благодарю всех, кто внес вклад в то, что было для меня довольно образовательным.

...