javascript - 这个扩展的 `compose` 函数的好名字是什么?

标签 javascript functional-programming

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

我一直在构建一个 new functional programming library 在 Javascript 中,我最近添加了一个对我来说很有用的新函数。我将其命名为 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!

...因为没有设施可以传递第二个参数,compose 中的 table

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

var project = useWith(map, pick);

不过,我让它比这个案例更通用。最初的方法被称为 using,参数颠倒过来,因此它读作命令:“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)));
    };
});

最佳答案

由于缺乏 javascript 知识,我可能误解了一些东西,但是如果 map 是一个柯里化(Currying)函数,而 compose 返回一个柯里化(Currying)函数,那么 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 的元数——您可以随意扩展 eta,因此,不需要额外的工作来进行泛化。只要所有东西都是柯里化(Currying)的。

为了同时具有混合元数、curried 和 uncurried 函数,有像 these 这样的组合器。 ,但这可能有点太极端了。

关于javascript - 这个扩展的 `compose` 函数的好名字是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17386706/

相关文章:

java - IntSummaryStatistics 的 summaryStatistics 方法

functional-programming - 在 Erlang 中编程时可以忽略线程安全吗?

javascript - 减少多维数组求和js的错误

javascript - 我如何遍历 Array.prototype 函数

javascript - 让 JavaScript 每 5 秒更换一次背景图片

javascript - firebase 通过 orderByChild 抓取然后更新结果键

javascript - 注入(inject)不纯函数与调用它有何不同?

javascript - 使用javascript 下载base64 数据| IE11

scala - 基本 Scalaz 状态问题

scala - 什么功能技术使得不必通过功能传递配置