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)
连续数字的阿兹特克神
由于它类似于"折叠"但不会将列表折叠成单个值,"折痕"怎么样?如果你保持"折痕",你最终会"折叠"(有点).
我们可以用烹饪比喻来称之为"捏",就像捏馅饼的外壳一样,虽然这可能暗示了圆形拉链,其中列表的最后一个元素与第一个元素配对.
def pinch(f, l):
return map(lambda t: f(*t), zip(l, l[1:]+l[:1]))
Run Code Online (Sandbox Code Playgroud)
(如果您只喜欢"折痕"或"捏"中的一个,请注意以作为评论.这些应该是单独的建议吗?)
在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)
我认为这是有道理的,因为当你用身份函数调用它时,它只返回对.
这是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是一个更好的名字
我确实在 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)