gpt4 book ai didi

javascript - 如何实现一个仿函数,使 map 可以应用于两个函数?

转载 作者:行者123 更新时间:2023-11-30 00:07:54 24 4
gpt4 key购买 nike

在 Haskell 中,您可以将 fmap 应用于两个函数,这基本上是函数组合。您甚至可以编写 fmap 以启用具有更高元数的函数的函数组合 (fmap . fmap)。

这是可行的,因为函数是仿函数。

如何在 Javascript 中实现这样的仿函数(或适当的 map 方法)?

这是我目前尝试过的:

funcProto = {
map(f) { return y => f(this.x(y)) }
};

function func(x) {
return Object.assign(Object.create(funcProto), {x: x});
}

const comp = f => g => x => f(g(x));
const map = f => ftor => ftor.map(f);
const sub = y => x => x - y;
const sqr = x => x * x;
const inc = x => x + 1;

这适用于正常的函数组合:

func(sqr).map(inc)(2); // 5

但是,它不适用于 map 的组合版本:

const map2 = comp(map)(map);
map2(sub)(sub)(10)(5)(4); // Error

我想我太适应了在 Javascript 中实现仿函数的传统方式。作为仿函数的函数与 list 或 maybe 的行为不同。

最佳答案

在 Haskell 中,一切都是函数。在您的 javascript 中,您的一些函数表示为带有 .x() 方法的 func,而一些是 native Function。那行不通。

这里有三种方法:

const sub = y => x => x - y;
const sqr = x => x * x;
const inc = x => x + 1;
const comp = f => g => x => f(g(x));
  • 普通函数,没有方法。

    const fmap = comp; // for functions only
    console.log(fmap(inc)(sqr)(1)) // 5
    const fmap2 = comp(fmap)(fmap);
    console.log(fmap2(sub)(sub)(10)(5)(4)); // 9
  • 扩展原生 Function,使用 fmap 作为方法:

    Function.prototype.fmap = function(f) { return comp(this)(f); };
    console.log(sqr.fmap(inc)(1)); // 5
    const fmap2 = comp.fmap(comp) // not exactly what you want, works just like above
    Function.prototype.fmap2 = function(f) { return this.fmap(g => g.fmap(f)); } // better
    console.log(sub.fmap2(sub)(10)(5)(4)); // 9
  • 构建您自己的函数类型(也在 ES6 中):

    function Func(f) {
    if (!new.target) return new Func(f);
    this.call = f;
    }
    // Ahem.
    const sub = Func(y => Func(x => x - y));
    const sqr = Func(x => x * x);
    const inc = Func(x => x + 1);
    const comp = Func(f => Func(g => Func(x => f.call(g.call(x)))));
    // Now let's start
    const fmap = Func(f => Func(x => x.fmap(f))); // a typeclass!
    Func.prototype.fmap = function(f) { return comp(this)(f); }; // an instance of the class!
    console.log(fmap.call(inc).call(sqr).call(1)); // 5
    const fmap2 = comp.call(fmap).call(fmap);
    console.log(fmap2.call(sub).call(sub).call(10).call(5).call(4)); // 9

关于javascript - 如何实现一个仿函数,使 map 可以应用于两个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37778811/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com