Есть ли имя для функции, которая возвращает позиционно-расширяющуюся версию своего аргумента? - PullRequest
1 голос
/ 25 февраля 2012

Рассмотрим splatter в этом коде Python:

def splatter(fn):
    return lambda (args): fn(*args)

def add(a, b):
    return a + b

list1 = [1, 2, 3]
list2 = [4, 5, 6]
print map(splatter(add), zip(list1, list2))

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

Редактировать

Ух, Python's map делает это автоматически. Вы можете написать:

map(add, list1, list2)

И это будет делать правильно, избавляя вас от необходимости splatter выполнять вашу функцию. Единственное отличие состоит в том, что zip возвращает список, длина которого равна длине его кратчайшего аргумента, тогда как map расширяет более короткие списки с помощью None.

Ответы [ 2 ]

1 голос
/ 11 марта 2013

Я думаю, zipWith - это функция, которую вы ищете (это имя, по крайней мере, используется в Haskell). Это даже немного более общее. В Haskell zipWith определяется следующим образом (где первая строка - это просто тип):

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = []

И ваш пример будет что-то вроде

zipWith (+) [1, 2, 3] [4, 5, 6]

Поскольку я не очень хорошо знаю Python, я могу указать только на « zip с аналогом в Python? ».

0 голосов
/ 04 марта 2016

Я случайно увидел это в своем списке «Заданных вопросов» и был удивлен, что теперь я знаю ответ.

Есть две интерпретации функции, которую я спросил.

Первым было мое намерение: взять функцию, которая принимает фиксированное количество аргументов, и преобразовать ее в функцию, которая принимает эти аргументы в виде списка или кортежа фиксированного размера. В Haskell функция, которая выполняет эту операцию, называется uncurry.

uncurry :: (a -> b -> c) -> ((a, b) -> c)

(Дополнительные символы для ясности.)

Легко представить, что это распространяется на функции более чем двух аргументов, хотя это не может быть выражено в Haskell. Но uncurry3, uncurry4 и т. Д. Не будут неуместны.

Так что я был прав, что это «смутно вызывает карри», поскольку на самом деле все наоборот.


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

Поскольку splat является настолько странным, как синтаксическая конструкция в Python, об этом трудно рассуждать.

Но если мы представим, скажем, JavaScript, который имеет первоклассную именованную функцию для "splatting:"

varFn.apply(null, args)

var splatter = function(f) {
    return function(arg) {
        return f.apply(null, arg);
    };
};

Тогда мы можем перефразировать это как частичное применение функции "apply":

var splatter = function(f) {
    return Function.prototype.apply.bind(f, null);
};

Или, используя Underscore's partial, мы можем придумать бессмысленное определение:

var splatter = _.partial(Function.prototype.bind.bind(Function.prototype.apply), _, null)

Да, это кошмар.

(Альтернатива _.partial требует определения своего рода swap помощника и, я думаю, будет еще менее читабельным.)

Так что я думаю, что название этой операции - просто "частичное применение apply", или в случае с Python это почти похоже на секцию оператора splat - если splat был «фактический» оператор.


Но конкретная комбинация uncurry, zip и map в исходном вопросе в точности равна zipWith, , как указала Крис . Фактически, HLint по умолчанию включает в себя правило для замены этой сложной конструкции одним вызовом zipWith.


Надеюсь, это прояснит ситуацию, после Иана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...