如何在 Lodash/FP 中组合函数然后应用参数

Dav*_*ith 4 javascript currying function-composition lodash

我试图通过使用 Lodash/FP 清理一些旧代码来了解更多关于在函数式编程中使用柯里化和组合的知识。但是,我反复遇到我有一个函数并且我想传递一个或多个函数的情况。然后我想将将用作参数的值传递给我传递给原始函数的函数。

我发现很难准确解释我想要做什么,所以我制作了一个 JS Fiddle,展示了我是如何尝试解决这个问题的:https : //jsfiddle.net/harimau777/rqkLf1rg/2/

const foo = a => `${a}${a}`
// Desired Behavior: const ans1 = (a, b) => `${foo(a)}${foo(b)}`
const ans1 = _.compose(
    (a, b) => `${a}${b}`,
  foo,
  foo
)
// Desired Result: '1122'
console.log(ans1('1', '2'))

// Desired Behavior: const ans2 = a => a.map(a => a + 1)
const ans2 = _.compose(
    _.map,
  a => a + 1
)
//Desired Result: [2, 3, 4]
console.log(ans2([1, 2, 3]))
Run Code Online (Sandbox Code Playgroud)

根据下面 Ori Drori 的回答,我认为我可以澄清我的问题(这是人们通常如何跟进 StackOverflow 而不是提出新问题?):假设不是将相同的函数序列应用于我想要的两个输入将一系列函数应用于第一个输入,将不同的序列应用于第二个输入,并将两个结果用作 _.compose 其余部分的输入。我可以使用:

const f1 = _.compose(<Some sequence of functions>)
const f2 = _.compose(<Some sequence of functions>)
const f3 = <A function which takes two inputs>
const ans = _.compose(
  <More functions here>,
  f3
)(f1(a), f2(b))
console.log(ans)
Run Code Online (Sandbox Code Playgroud)

但是,我想知道是否有办法使用单个组合来处理这个问题,或者是否有任何模式倾向于在函数式编程中使用来处理这样的情况。

Ori*_*ori 7

LodashFPs _.compose()_.flowRight()在 lodash 中)的工作原理是将参数应用于最右侧(代码中的底部)的函数,并将结果传递给左侧的函数,依此类推:

_.compose(a, b, c)(params) -> a(b(c(params)))
Run Code Online (Sandbox Code Playgroud)

这意味着除了最右边的每个函数都只接收一个参数。

您可以通过稍微更改方法来使第一个示例工作:

_.compose(a, b, c)(params) -> a(b(c(params)))
Run Code Online (Sandbox Code Playgroud)
const ans1 = _.compose(
  arr => arr.join(''), // joins the params to one string
  (...args) => args.map((s) => `${s}${s}`) // returns an array of double params
)

// Desired Result: '1122'
console.log(ans1('1', '2'))
Run Code Online (Sandbox Code Playgroud)

在第二个示例中,您希望创建一个通过预定义回调映射的新方法。由于lodash / fp的方法是汽车令行禁止,您可以提供回调的_.map(),并获得了新的方法。Compose 在这里不起作用,因为_.map()它不直接使用该方法的结果,而是将其应用于数组中的每个项目:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
const ans2 = _.map(a => a + 1)

//Desired Result: [2, 3, 4]
console.log(ans2([1, 2, 3]))
Run Code Online (Sandbox Code Playgroud)


您在澄清中提出的案例可以由_.useWith()_.overArgs()在 lodash 中称为)处理:

创建一个函数,该函数调用 func 并转换其参数。

但是,不建议使用它,因为它会降低可读性。

例子:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
const foo = a => `${a}${a}`

const ans1 = _.useWith(
  (a, b) => `${a}${b}`,
  [
    foo,
    foo
  ]
)

const result = ans1(1, 2)

console.log(result)
Run Code Online (Sandbox Code Playgroud)