6

我有一个搜索名字的功能。

我一直在用 Javascript 构建一个新的函数式编程库,最近我添加了一个看起来对我有用的新函数。我命名了它,useWith但我想知道它是否是函数式程序员已经知道的另一个名称的函数。

该函数的相关之处compose在于它返回一个新函数,该函数结合了几个现有函数,但方式与compose. 它接收到的第一个参数被挑出;其余的统一处理。当调用返回的函数时,参数将分别传递给这些剩余函数中的每一个,并将结果与​​任何未配对的参数一起发送给第一个函数,然后返回其结果。因此,如果仅使用两个函数调用 this,并且结果函数仅传递一个参数,则 this 完全等效于 compose。但它有一些针对多个参数的附加功能。

我想要这个函数的原因是我正在实现类似函数式Javascriptproject中呈现的函数 Michal Fogus的东西,它相当于 Codd 的类似 Javascript 对象数组的函数,并且类似于 SQL 的动词。像这样写很容易:projectselect

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!

...因为没有工具可以通过第二个参数tableinside 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)));
    };
});
4

1 回答 1

4

由于缺乏 javascript 知识,我可能会误解某些东西,但是 ifmap是一个 curried 函数,并compose返回一个 curried 函数,然后compose(map, pick) is 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- 您可以随意进行 eta-expand,因此,泛化不需要额外的工作。只要一切都是咖喱。

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

于 2013-07-01T15:04:55.180 回答