如何使用 Lodash 流组合不同数量的函数? [英] How to compose functions of varying arity using Lodash flow?

查看:22
本文介绍了如何使用 Lodash 流组合不同数量的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做一些函数组合.我已经知道了:

I want to do some function composition. I know already this:

如果 f3(x) 应与 f1(f2(x)) 相同然后 f3 = _.flowRight(f1,f2);

If f3(x) shall be the same as f1(f2(x)) then f3 = _.flowRight(f1,f2);

如果 f3(x,y) 应与 f1(x, f2(y)) 相同那么……?

If f3(x,y) shall be the same as f1(x, f2(y)) then …?

(用例是node.js/express中间件函数的组合.)

(The use case is the composition of node.js/express middleware functions.)

推荐答案

在以下图像中,我使用 {_} 作为值的占位符.把它想象成代码中的一个,我们可以在其中传递一些东西.

In the following images, I use {_} as a placeholder for a value. Think of it as a hole in the code where we pass something in.

好吧,让我们想象一下你的函数必须做什么......

Ok let's imagine what your function would have to do...

  • 这看起来像一个通用的转换吗?即,您认为我们可以在很多地方使用它吗?–函数式编程促进构建高度可重用且可以多种方式组合的函数.
  • f1f2 有什么区别?f1 是一个只能得到一个参数的一元函数,f2 是一个可以得到两个参数的二元函数.你会记得哪个去哪个地方吗?
  • 什么控制了 f1(x)f2 中的位置?
    • 比较f2(y,f1(x)) ...
    • f2(f1(x),y)
    • 其中一个比另一个更有用吗?
    • 你会记住 f1 的位置吗?
    • Does this seems like a generic transformation? ie, do you think we can use this in many places? – functional programming promotes building functions which are highly reusable and can be combined in various ways.
    • What is the difference between f1 and f2? f1 is a unary function which will only get one arg, f2 is a binary function which will get two. Are you going to remember which one goes in which place?
    • What governs the position that f1(x) gets placed in f2?
      • Compare f2(y,f1(x)) ...
      • to f2(f1(x),y)
      • is one of those more useful than the other?
      • are you going to remember which position f1 gets?

      回想一下,函数组合应该能够将任意数量的函数链接在一起.为了帮助您理解 someFunc 的无用性,让我们假设它最多接受 3 个函数和 3 个参数.

      Recall that function composition should be able to chain as many functions together as you want. To help you understand the futility of someFunc, let's imagine it accepting up to 3 functions and 3 arguments.

      • 这里还有模式吗?也许吧,但你仍然有笨拙的一元函数 f1,它只得到一个 arg,而 f2f3 每个得到 2
      • f2f3 是否真的需要总是 右侧的前一个函数调用的值?
        • 比较f3(z,f2(y,f1(x)))
        • f3(f2(y,f1(x)),z)
        • 也许 f3 需要从左边链接,但 f2 从右边链接?
        • 我无法想象你的整个二元函数 API 会神奇地需要在同一个地方链接参数
        • Is there even a pattern here? Maybe, but you still have the awkward unary function f1 that only gets one arg, while f2 and f3 each get 2
        • Is it true that f2 and f3 are going need the value of the previous function calls on the right side always ?
          • Compare f3(z,f2(y,f1(x)))
          • to f3(f2(y,f1(x)),z)
          • Maybe f3 needs to chain left, but f2 chains from the right?
          • I can't imagine your entire API of binary functions would magically need chained arguments in the same place

          答案是自我实现

          函数组合在这里被滥用.函数组合几乎只在您组合一元函数时才有效(每个函数接受 1 个参数).当混入更高数量的函数时,它立即崩溃并且无法推广.

          Function composition is being misused here. Function composition pretty much only works when you're composing unary functions exclusive (functions accepting 1 argument each). It immediately breaks down and cannot be generalised when mixing in functions of higher arity.

          现在回到你的代码,如果f3需要一个名字,它是f1f2和两个参数的组合,它应该清楚地表达为…

          Going back to your code now, if f3 needs a name and it is the combination of f1, f2, and two parameters, it should be plainly expressed as …

          const f3 = (x,y) => f1(x, f2(y))
          

          因为它做出了如此多的任意选择,所以不能以任何有用的方式概括.就这样吧.

          Because it makes so many arbitrary choices, it cannot be generalized in any useful way. Just let it be as it is.

          那么有没有办法组合不同数量的函数?"

          当然,有几种不同实用性的技术.我将在这里演示高度实用的 partial 函数的使用

          Sure, there are a couple techniques of varied practicality. I'll demonstrate use of the highly practical partial function here

          const partial = (f,...xs) => (...ys) => f(...xs, ...ys)
          
          const add = (x,y) => x + y
          
          const mult = (x,y) => x * y
          
          const sq = x => mult (x,x)
          
          // R.I.P. lodash.flowRight
          const compose = ([f,...fs]) => x =>
            f === undefined ? x : f (compose (fs) (x))
                            
          let f = compose([partial(add, 1), sq, partial(mult, 3)])
          
          console.log(f(2))
          // add(1, square(mult(3, 2)))
          // add(1, square(6))
          // add(1, 36)
          // => 37

          哦,顺便说一下,我们替换了 Lodash 的 flowRight(复杂的 flow) 与一行代码.

          Oh, by the way, we replaced Lodash's flowRight (wrapper of the complex flow) with a single line of code.

          这篇关于如何使用 Lodash 流组合不同数量的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆