Как мы называем эту (новую?) Функцию высшего порядка? - PullRequest
10 голосов
/ 23 сентября 2010

Я пытаюсь назвать то, что я считаю новой идеей для функции более высокого порядка.Что важно, вот код на Python и Haskell для демонстрации концепции, которая будет объяснена позже.

Python:

>>> def pleat(f, l):
       return map(lambda t: f(*t), zip(l, l[1:]))
>>> pleat(operator.add, [0, 1, 2, 3])
[1, 3, 5]

Haskell:

Prelude> let pleatWith f xs = zipWith f xs (drop 1 xs)
Prelude> pleatWith (+) [0,1,2,3]
[1,3,5]

Как вы можете сделать вывод, последовательность повторяется, используя соседние элементы в качестве параметров для функции, которую вы передаете, проецируя результаты в новую последовательность.Итак, кто-нибудь видел функциональность, которую мы создали?Это вообще знакомо тем, кто в функциональном сообществе?Если нет, то как мы называем это?

---- Update ----

Плисс побед!

Prelude> let pleat xs = zip xs (drop 1 xs)
Prelude> pleat [1..4]
[(1,2),(2,3),(3,4)]

Prelude> let pleatWith f xs = zipWith f xs (drop 1 xs)
Prelude> pleatWith (+) [1..4]
[3,5,7]

Ответы [ 16 ]

17 голосов
/ 23 сентября 2010

Хмм ... контрапункт.

(`ap` tail) . zipWith

не заслуживает имени.

Кстати, ртуть говорит:

 zip`ap`tail

Ацтекский богпоследовательные номера

6 голосов
/ 23 сентября 2010

В Python эквивалент meld находится в рецептах itertools и называется попарно.

from itertools import starmap, izp, tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

Так я бы назвал это:

def pairwith(func, seq):
    return starmap(func, pairwise(seq))

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

6 голосов
/ 23 сентября 2010

Поскольку это похоже на «сворачивание», но не сворачивает список в одно значение, как насчет «сгиба»?Если вы продолжаете «складываться», вы в конечном итоге «складываетесь» (вроде).

Мы могли бы пойти с метафорой приготовления пищи и назвать ее «щепоткой», подобно зажиму корки пирога, хотя это может означать кольцевое сжатие, когда последний элемент списка соединяется с первым.

def pinch(f, l):
    return map(lambda t: f(*t), zip(l, l[1:]+l[:1]))

(Если вам нравится только один из «складки» или «щипок», пожалуйста, отметьте это как комментарий. Это должны быть отдельные предложения?)

5 голосов
/ 23 сентября 2010

Вот еще одна реализация для Python, которая работает, если l тоже генератор

import itertools as it

def apply_pairwise(f, l):
    left, right = it.tee(l)
    next(right)
    return it.starmap(f, it.izip(left, right))

Я думаю apply_pairwise - лучшее имя

4 голосов
/ 23 сентября 2010

Я действительно не вижу никаких кодифицированных имен для этого в Python, это точно.«Слияние» - это хорошо, но о нем говорят в самых разных контекстах.«Плуг», как правило, не используется и обеспечивает отличное визуальное представление о постоянном проталкивании линии почвы.Возможно, я просто слишком много времени уделял садоводству.

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

Вы также можете подумать: складка.Он хорошо описывает, как вы берете список (например, длинный отрезок ткани) и собираете его воедино.

import operator

def stagger(l, w):
    if len(l)>=w:
        return [tuple(l[0:w])]+stagger(l[1:], w)
    return []

def pleat(f, l, w=2):
    return map(lambda p: f(*p), stagger(l, w))

print pleat(operator.add, range(10))
print pleat(lambda x, y, z: x*y/z, range(3, 13), 3)
print pleat(lambda x: "~%s~"%(x), range(10), 1)
print pleat(lambda a, b, x, y: a+b==x+y, [3, 2, 4, 1, 5, 0, 9, 9, 0], 4)
2 голосов
/ 24 сентября 2010

в стандартной библиотеке шаблонов C ++, она называется acent_difference (хотя оператором может быть любая операция, а не только вычитание)

2 голосов
/ 23 сентября 2010

Обобщенный вариант простой zip-версии этого я бы назвал window.Не в терминале ghci прямо сейчас, но я думаю window n = take n . tails.Тогда ваша функция zipWith (\[x,yj -> f x y) . window 2.Этот стиль естественно работает лучше, когда f имеет тип [a] -> b.

2 голосов
/ 23 сентября 2010

Это напоминает мне о свертке от обработки изображения.Но не уверен, что это математически правильно.

2 голосов
/ 23 сентября 2010

это похоже на рубин each_cons

ruby-1.9.2-p0 > (1..10).each_cons(2).to_a

=> [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]] 
2 голосов
/ 23 сентября 2010

Я голосую за smearWith или smudgeWith, потому что вы как будто размазываете / размазываете операцию по всему списку.

...