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

时间:2018-01-24 15:51:34

标签: javascript lodash currying function-composition

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

我发现很难准确解释我正在尝试做什么,所以我制作了一个JS小提琴,展示了我一直在努力解决这个问题: 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]))

根据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)

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

1 个答案:

答案 0 :(得分:2)

LodashFPs _.compose()(lodash中的_.flowRight())通过将参数应用到最右侧(代码底部)函数,并将结果传递给函数左侧,依此类推:

_.compose(a, b, c)(params) -> a(b(c(params)))

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

您可以通过稍微更改方法来获得第一个示例:

const ans1 = _.compose(
  (...args) => args.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'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.min.js"></script>

在第二个示例中,您要创建一个通过预定义回调映射的新方法。由于lodash / fp方法是自动curried,因此您可以向_.map()提供回调,并获取新方法。 Compose在这里不起作用,因为_.map()不直接使用方法的结果,而是将其应用于数组中的每个项目:

const ans2 = _.map(a => a + 1)

//Desired Result: [2, 3, 4]
console.log(ans2([1, 2, 3]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.min.js"></script>

如果您想要一个功能更强大的库,您可能想尝试RamdaJS。您在澄清时提出的案例可由R.useWith处理:

  

接受函数fn和变换器函数列表并返回   一个新的咖喱功能。当调用新函数时,它会调用   函数fn,其参数由调用每个参数组成   在新函数的连续参数上提供了处理程序。

示例:

const foo = a => `${a}${a}`

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

const result = ans1(1, 2)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>