最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to compose functions and then apply arguments in LodashFP - Stack Overflow

programmeradmin3浏览0评论

I am trying to learn more about using currying and position in functional programming by using Lodash/FP to clean up some old code. However, I am repeatedly running into situations where I have a function and I want to pass it one or more functions. I then want to pass the values that will be used as the arguments to the functions that I passed to the original function.

I'm finding it difficult to explain exactly what I'm trying to do so I made a JS Fiddle that shows how I have been trying to approach this: /

const foo = a => `${a}${a}`
// Desired Behavior: const ans1 = (a, b) => `${foo(a)}${foo(b)}`
const ans1 = _pose(
    (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 = _pose(
    _.map,
  a => a + 1
)
//Desired Result: [2, 3, 4]
console.log(ans2([1, 2, 3]))

Based on Ori Drori's answer below I think that I can clarify my question (is this how people normally follow up on StackOverflow as opposed to asking a new question?): Suppose that instead of applying the same sequence of functions to both inputs I wanted to apply a sequence of functions to the first input, a different sequence to the second input, and use both results as the input to the rest of the _pose. I could do this using:

const f1 = _pose(<Some sequence of functions>)
const f2 = _pose(<Some sequence of functions>)
const f3 = <A function which takes two inputs>
const ans = _pose(
  <More functions here>,
  f3
)(f1(a), f2(b))
console.log(ans)

However, I'm wondering if there is a way to handle this using a single pose or if there are any patterns that tend to be used in functional programming to handle situations like this.

I am trying to learn more about using currying and position in functional programming by using Lodash/FP to clean up some old code. However, I am repeatedly running into situations where I have a function and I want to pass it one or more functions. I then want to pass the values that will be used as the arguments to the functions that I passed to the original function.

I'm finding it difficult to explain exactly what I'm trying to do so I made a JS Fiddle that shows how I have been trying to approach this: https://jsfiddle/harimau777/rqkLf1rg/2/

const foo = a => `${a}${a}`
// Desired Behavior: const ans1 = (a, b) => `${foo(a)}${foo(b)}`
const ans1 = _.pose(
    (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 = _.pose(
    _.map,
  a => a + 1
)
//Desired Result: [2, 3, 4]
console.log(ans2([1, 2, 3]))

Based on Ori Drori's answer below I think that I can clarify my question (is this how people normally follow up on StackOverflow as opposed to asking a new question?): Suppose that instead of applying the same sequence of functions to both inputs I wanted to apply a sequence of functions to the first input, a different sequence to the second input, and use both results as the input to the rest of the _.pose. I could do this using:

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

However, I'm wondering if there is a way to handle this using a single pose or if there are any patterns that tend to be used in functional programming to handle situations like this.

Share Improve this question edited Jan 25, 2018 at 15:33 David Moneysmith asked Jan 24, 2018 at 15:51 David MoneysmithDavid Moneysmith 8992 gold badges9 silver badges10 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 11

LodashFPs _.pose() (_.flowRight() in lodash) works by applying the parameters to the right most (bottom in your code) function, and passes the result to the function to it's left, and so on:

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

This means that every function, except for the right most receives only one parameter.

You can get the 1st example working by changing the methods a bit:

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

In the 2nd example you want to create a new method that maps via a predefined callback. Since lodash/fp methods are auto curried, you can supply the callback to the _.map(), and get a new method. Compose won't work here since _.map() doesn't use the results of the method directly, but applies it to every item in the array:

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

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


The case you've presented in your clarification can be handled by _.useWith() (known as _.overArgs() in lodash):

Creates a function that invokes func with its arguments transformed.

However, it's use is not remended since it reduces readability.

Example:

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

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

const result = ans1(1, 2)

console.log(result)
<script src='https://cdn.jsdelivr/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>

发布评论

评论列表(0)

  1. 暂无评论