这个扩展的'compose`函数有什么好名字?

时间:2013-06-30 02:57:41

标签: javascript functional-programming

我有一个寻找名字的功能。

我在Javascript中构建了一个 new functional programming library ,最近我添加了一个对我有用的新功能。我把它命名为useWith,但我想知道它是否是功能程序员用不同名称已知的函数。

该函数与compose有关,因为它返回一个新函数,它结合了几个现有函数,但方式与compose略有不同。它接收的第一个参数被挑选出来;其余部分均匀处理。当调用返回的函数时,参数将分别传递给其余每个函数,结果以及任何未配对的参数将被发送到第一个函数,然后返回其结果。因此,如果仅使用两个函数调用它,并且如果结果函数传递一个参数,则这与compose完全等效。但它有多个参数的附加功能。

我想要这个功能的原因是我正在实现类似project功能的东西 Michal Fogus以 Functional Javascript 呈现,相当于Codd的project,用于类似Javascript对象的数组,类似于SQL的select动词。写这样很容易:

var project = curry(function(keys, table) {
    return map(pick(keys), table);
});


// Used like this:
var kids = [{name: 'Bob', age: 3, eyes: 'blue', hair: 'brown'}, 
            {name: 'Sue', age: 5, eyes: 'hazel', hair: 'blonde'}];
project(['name', 'eyes'], kids); 
//=> [{name: 'Bob', eyes: 'blue'}, {name: 'Sue', eyes: 'hazel'}]

但我真的想以无点的方式实现它。但当然这不起作用:

var project = compose(map, pick); // NO!

...因为没有设施通过table内的第二个参数compose

这就是新功能的用武之地:

var project = useWith(map, pick);
但是,我比这种情况更通用了。原始方法称为using,参数反转,因此它作为命令读取:“使用pick,map”。但这使得很难扩展到多个参数。我必须让第一个数组成为数组,或者允许它成为数组或单个函数,我真的不想去那里。这似乎是一个更好的解决方案。

我觉得好像我不能成为第一个需要这样功能的人。这是FP语言中的常见模式吗?这个功能有一个共同的名称吗?如果没有,是否有比useWith更好的名称的建议?


如果您感到好奇,这里是useWith的实施,使用非常明显的slice和相当标准的curry

var useWith = curry(function(fn /*, tranformers */) {
    var tranformers = slice(arguments, 1);
    return function() {
        var args = [], idx = -1;
        while (++idx < tranformers.length) {
            args.push(tranformers[idx](arguments[idx]))
        }
        return fn.apply(this, args.concat(slice(arguments, tranformers.length)));
    };
});

1 个答案:

答案 0 :(得分:4)

由于缺乏javascript知识,我可能会误解某些内容,但如果map是一个curried函数,并且compose返回一个curried函数,那么compose(map, pick) project,因为map部分应用于pick - 部分应用仅适用于第一个参数。这是我的意思的证明:

compose map pick =
(\f g x. f (g x)) map pick =         -- definition of compose
(\g x. map (g x)) pick =             -- apply to map
\x. map (pick x) =                   -- apply to pick
\x. (\y. map (pick x) y) =           -- eta-expansion of inner function
\key table. map (pick key) table     -- combine and rename

(我假设您根据图书馆的名称了解lambda演算。)

正如您所看到的,这不依赖于map的优点 - 您可以随意扩展,因此,不需要额外的工作来进行泛化。只要一切都是咖喱的。

对于同时具有混合功能,咖喱和非功能的功能,有像these这样的组合器,但这可能有点过于极端。