我们称这个(新的?)高阶函数为啥?

9 投票
16 回答
2379 浏览
提问于 2025-04-16 04:28

我在想给一个我认为是新想法的高阶函数起个名字。我想叫它“二元投影”,但我的同伴想叫它“犁”。我们还讨论过叫它“雪地清扫机”。不过,重要的部分是,下面是用Python和Haskell展示这个概念的代码,之后会进行解释。

Python:

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

Haskell:

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

你可能能猜到,这个序列正在被遍历,利用相邻的元素作为你传入的函数的参数,然后把结果投影到一个新的序列中。那么,有人见过我们创建的这个功能吗?对于那些了解函数式编程的人来说,这个概念熟悉吗?如果不熟悉,我们该怎么给它命名呢?

---- Update ----

现在有三个候选名字:meldpinchpleat。在Haskell中,它们可以这样实现(使用“meld”):

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

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

我觉得该投票了。我个人比较倾向于“pinch”或“pleat”。

16 个回答

6

在Python中,meld的类似功能在itertools的配方中,叫做pairwise。

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))

我觉得这样很合理,因为当你用身份函数调用它时,它会简单地返回成对的元素。

17

嗯……这是个反对的观点。

(`ap` tail) . zipWith

不值得给它起个名字。

顺便说一下,quicksilver说:

 zip`ap`tail

这是阿兹特克神话中关于连续数字的神。

4

我在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)

撰写回答