【问题标题】:Is there a name for the function that returns a positionally-expanding version of its argument?是否有返回其参数的位置扩展版本的函数的名称?
【发布时间】:2012-03-15 09:31:45
【问题描述】:

在此 Python 代码中考虑 splatter

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 的 map 会自动执行此操作。你可以写:

map(add, list1, list2)

它会做正确的事,为您省去splatter您的功能的麻烦。唯一的区别是zip 返回一个列表,其长度是其最短参数的长度,而map 使用None 扩展较短的列表。

【问题讨论】:

    标签: higher-order-functions splat


    【解决方案1】:

    我认为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不太了解,所以只能指向“zipWith analogue in Python?”。

    【讨论】:

      【解决方案2】:

      我在“提出的问题”列表中随机看到了这个问题,很惊讶我现在知道了答案。

      我问的函数有两种解释。

      第一个是我的意图:获取一个带有固定数量参数的函数,并将其转换为一个将这些参数作为固定大小列表或元组的函数。在 Haskell 中,执行此操作的函数称为 uncurry

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

      (为了清楚起见,额外的括号。)

      很容易想象将其扩展到具有两个以上参数的函数,尽管它不能在 Haskell 中表达。但uncurry3uncurry4等不会不合适。

      所以我是对的,它“隐约地唤起了咖喱”,因为它实际上恰恰相反。


      第二种解释是采用一个带有有意可变数量参数的函数,并返回一个采用单个列表的函数。

      因为splat 在 Python 中作为一个语法结构非常奇怪,所以这很难推理。

      但如果我们想象一下,比如 JavaScript,它有一个用于“喷溅”的一流命名函数:

      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 运算符的 section ——如果 splat 是一个“实际”运算符.


      但在原始问题中uncurryzipmap 的特定组合恰好是zipWithas chris pointed out。事实上,HLint 默认使用includes a rule 来替换这个复杂的构造,只需调用zipWith


      我希望这能解决问题,Ian 过去了。

      【讨论】:

        猜你喜欢
        • 2013-10-14
        • 1970-01-01
        • 2014-10-12
        • 2012-02-04
        • 2021-08-09
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 2015-07-19
        相关资源
        最近更新 更多