gpt4 book ai didi

javascript - 如何协调 Javascript 与柯里化(Currying)和函数组合

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:56:02 25 4
gpt4 key购买 nike

我喜欢 currying,但有几个原因可以解释为什么很多 Javascript 开发人员拒绝这种技术:

  • 对典型 curry 图案的审美关注:f(x) (y) (z)
  • 担心由于函数调用数量增加而导致的性能损失
  • 由于许多嵌套匿名函数而引起的调试问题的担忧
  • 关注无点样式的可读性(与组合相关的柯里化(Currying))

  • 有没有一种方法可以减轻这些担忧,让我的同事不讨厌我?

    最佳答案

    Note: @ftor answered his/her own question. This is a direct companion to that answer.



    你已经是天才了

    我想你可能已经重新想象了 partial功能——至少,部分!
    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

    它是对应的, partialRight
    const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);
    partial接受一个函数,一些参数( xs ),并始终返回一个接受更多参数的函数( ys ),然后应用 f(...xs, ...ys)
    初始备注

    这个问题的背景是柯里化(Currying)和组合如何与大量的编码器用户群配合得很好。我的言论将在相同的背景下
  • 仅仅因为一个函数可能返回一个函数并不意味着它被柯里化(Currying)了——添加 _表示一个函数正在等待更多的参数是令人困惑的。回想一下,柯里化(Currying)(或部分函数应用程序)抽象了 arity,所以我们永远不知道函数调用何时会导致计算值或另一个函数等待被调用。
  • curry不应该翻转论点;这会给你的程序员同事造成一些严重的 wtf 时刻
  • 如果我们要为 reduce 创建一个包装器, reduceRight包装器应该是一致的——例如,你的 foldl使用 f(acc, x, i)但是你的foldr使用 f(x, acc, i) – 这会给不熟悉这些选择的同事带来很多痛苦

  • 对于下一部分,我将替换您的 composablepartial , 删除 _ -后缀,并修复 foldr包装

    可组合函数

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

    const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);

    const comp = (f, g) => x => f(g(x));

    const foldl = (f, acc, xs) => xs.reduce(f, acc);

    const drop = (xs, n) => xs.slice(n);

    const add = (x, y) => x + y;

    const sum = partial(foldl, add, 0);

    const dropAndSum = comp(sum, partialRight(drop, 1));

    console.log(
    dropAndSum([1,2,3,4]) // 9
    );



    程序化解决方案

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

    // restore consistent interface
    const foldr = (f, acc, xs) => xs.reduceRight(f, acc);

    const comp = (f,g) => x => f(g(x));

    // added this for later
    const flip = f => (x,y) => f(y,x);

    const I = x => x;

    const inc = x => x + 1;

    const compn = partial(foldr, flip(comp), I);

    const inc3 = compn([inc, inc, inc]);

    console.log(
    inc3(0) // 3
    );



    更严肃的任务

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

    const filter = (f, xs) => xs.filter(f);

    const comp2 = (f, g, x, y) => f(g(x, y));

    const len = xs => xs.length;

    const odd = x => x % 2 === 1;

    const countWhere = f => partial(comp2, len, filter, f);

    const countWhereOdd = countWhere(odd);

    console.log(
    countWhereOdd([1,2,3,4,5]) // 3
    );



    部分力量!
    partial实际上可以根据需要多次应用

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys)

    const p = (a,b,c,d,e,f) => a + b + c + d + e + f

    let f = partial(p,1,2)
    let g = partial(f,3,4)
    let h = partial(g,5,6)

    console.log(p(1,2,3,4,5,6)) // 21
    console.log(f(3,4,5,6)) // 21
    console.log(g(5,6)) // 21
    console.log(h()) // 21


    这也使它成为处理可变参数函数不可或缺的工具

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys)

    const add = (x,y) => x + y

    const p = (...xs) => xs.reduce(add, 0)

    let f = partial(p,1,1,1,1)
    let g = partial(f,2,2,2,2)
    let h = partial(g,3,3,3,3)

    console.log(h(4,4,4,4))
    // 1 + 1 + 1 + 1 +
    // 2 + 2 + 2 + 2 +
    // 3 + 3 + 3 + 3 +
    // 4 + 4 + 4 + 4 => 40


    最后, partialRight 的演示

    const partial = (f, ...xs) => (...ys) => f(...xs, ...ys);

    const partialRight = (f, ...xs) => (...ys) => f(...ys, ...xs);

    const p = (...xs) => console.log(...xs)

    const f = partialRight(p, 7, 8, 9);
    const g = partial(f, 1, 2, 3);
    const h = partial(g, 4, 5, 6);

    p(1, 2, 3, 4, 5, 6, 7, 8, 9) // 1 2 3 4 5 6 7 8 9
    f(1, 2, 3, 4, 5, 6) // 1 2 3 4 5 6 7 8 9
    g(4, 5, 6) // 1 2 3 4 5 6 7 8 9
    h() // 1 2 3 4 5 6 7 8 9



    总结

    好的,所以 partial几乎是 composable 的替代品但也解决了一些额外的极端情况。让我们看看这与您的初始列表有何不同
  • 审美问题:避免f (x) (y) (z)
  • 性能:不确定,但我怀疑性能大致相同
  • 调试:仍然是个问题,因为 partial创建新功能
  • 可读性:实际上,我认为这里的可读性非常好。 partial足够灵活,可以在许多情况下删除点

  • 我同意你的观点,完全柯里化(Currying)的函数是无可替代的。一旦我不再评判语法的“丑陋”,我个人发现采用新风格很容易——它只是不同,人们不喜欢不同。

    关于javascript - 如何协调 Javascript 与柯里化(Currying)和函数组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42164000/

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