Composing functions with multiple arguments

风流意气都作罢 提交于 2019-12-24 04:29:04

问题


How can I compose a function where apply takes more than one argument?

Here is a contrived example:

val sum: List[Int] => Int = l => l.sum

val double: Int => Int = i => i * i

double.compose(sum).apply(List(1,2,3)) //=> 36

val sumAppend: (List[Int], Int) => Int = (l, i) => i :: l sum

double.compose(sumAppend).apply(List(1,2,3), 1) // Attempt to append 1 to list then sum

The above give me a typed inferred error?


回答1:


Define compose2, for instance as an extension method for Function1:

implicit class ComposeFunction2[A, B, C, D](f1: Function1[C, D]) {
  def compose2(f2: Function2[A, B, C]): Function2[A, B, D] =
    (a: A, b: B) => f1(f2(a, b))
}

This will be faster than the alternatives as it does not allocate tuples. Usage:

scala> val double: Int => Int = i => i * i
double: Int => Int = <function1>

scala> val sumAppend: (List[Int], Int) => Int = (l, i) => i :: l sum
sumAppend: (List[Int], Int) => Int = <function2>

scala> double.compose2(sumAppend).apply(List(1,2,3), 1)
res5: Int = 49



回答2:


in this case you can compose only functions that takes single argument. so sumAppend has to be function that takes a single argument of any type and must return a result of Int (i.e. _ => Int).

you can convert a Function that takes two arguments to a curried function and partially apply the function as shown below.

scala> val sumAppend = (l: List[Int], i: Int) => (i :: l).sum
sumAppend: (List[Int], Int) => Int = $$Lambda$1630/1910012982@44511a58

scala> double.compose(sumAppend.curried.apply(List(1,2,3))).apply(10)
res18: Int = 256

One other option would be to have sumAppend take a single argument which is Tuple of List[Int] and Int.

scala> val sumAppend: ((List[Int], Int)) => Int = l => (l._2 :: l._1).sum
sumAppend: ((List[Int], Int)) => Int = $$Lambda$1597/1903597138@5fa9d195

scala> val x = double.compose(sumAppend).apply((List(1,2,3),10))
x: Int = 256


来源:https://stackoverflow.com/questions/44180861/composing-functions-with-multiple-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!