我们称之为(新的?)高阶函数?

Squ*_*ama 10 python theory haskell functional-programming higher-order-functions

我试图说出我认为对于更高阶函数的新想法.重要的是,这里是Python和Haskell中的代码来演示这个概念,后面将对此进行解释.

蟒蛇:

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

哈斯克尔:

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

正如您所能推断的那样,序列正在迭代,利用相邻元素作为传递函数的参数,将结果投影到新序列中.那么,有没有人看到我们创建的功能?这对功能社区的人来说是否熟悉?如果没有,我们怎么命名呢?

---- Update ----
Run Code Online (Sandbox Code Playgroud)

褶皱获胜!

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]
Run Code Online (Sandbox Code Playgroud)

Don*_*art 17

嗯...一个对应点.

(`ap` tail) . zipWith
Run Code Online (Sandbox Code Playgroud)

不值得一个名字.

BTW,quicksilver说:

 zip`ap`tail
Run Code Online (Sandbox Code Playgroud)

连续数字的阿兹特克神

  • 为什么不呢?作为反对点,`flip mapM`,`foldr(>>)(return())`和`liftM2 id`**被归为一些.(注意,我不是在争论它,我指出这个论点很弱) (2认同)
  • map和fold是两个基本的高阶函数,因此,这样的用法很常见.尾巴是中等罕见的,拉链`尾巴'非常罕见.罕见+琐碎==不是一个很好的理由来命名. (2认同)
  • 我不知道这一点,我认为其他人可能在同一条船上,无论他们使用Haskell多长时间.是否有任何地方可以通过一堆这些有用的代码片段,这些内容不像前奏代码那样常见,但足以制作这些帖子?或者大多数人自己偶然发现了这个? (2认同)

out*_*tis 6

由于它类似于"折叠"但不会将列表折叠成单个值,"折痕"怎么样?如果你保持"折痕",你最终会"折叠"(有点).

我们可以用烹饪比喻来称之为"捏",就像捏馅饼的外壳一样,虽然这可能暗示了圆形拉链,其中列表的最后一个元素与第一个元素配对.

def pinch(f, l):
    return map(lambda t: f(*t), zip(l, l[1:]+l[:1]))
Run Code Online (Sandbox Code Playgroud)

(如果您只喜欢"折痕"或"捏"中的一个,请注意以作为评论.这些应该是单独的建议吗?)

  • "犁"似乎不是一个好的描述,因为犁翻过来,破坏了东西并且通气,这些似乎都不适用于这个功能. (2认同)
  • 不,不,"折痕"显然意味着折叠然后展开. (2认同)

Joc*_*zel 6

在Python中,meld等价物位于itertools receipes中并称为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)
Run Code Online (Sandbox Code Playgroud)

所以我会称之为:

def pairwith(func, seq):
    return starmap(func, pairwise(seq))
Run Code Online (Sandbox Code Playgroud)

我认为这是有道理的,因为当你用身份函数调用它时,它只返回对.


Joh*_*ooy 5

这是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))
Run Code Online (Sandbox Code Playgroud)

我认为这apply_pairwise是一个更好的名字


Ish*_*eck 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)
Run Code Online (Sandbox Code Playgroud)