组合具有多个参数的函数
Composing functions with multiple arguments
如何编写一个 apply 接受多个参数的函数?
这是一个人为的例子:
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
以上给出了类型推断错误?
在这种情况下,您只能编写采用单个参数的函数。所以 sumAppend 必须是接受任何类型的单个参数的函数,并且必须 return Int 的结果(即 _ => Int
)。
您可以将带有两个参数的函数转换为柯里化函数并部分应用该函数,如下所示。
scala> val sumAppend = (l: List[Int], i: Int) => (i :: l).sum
sumAppend: (List[Int], Int) => Int = $$Lambda30/1910012982@44511a58
scala> double.compose(sumAppend.curried.apply(List(1,2,3))).apply(10)
res18: Int = 256
另一种选择是让 sumAppend 接受一个参数,即 List[Int] 和 Int 的元组。
scala> val sumAppend: ((List[Int], Int)) => Int = l => (l._2 :: l._1).sum
sumAppend: ((List[Int], Int)) => Int = $$Lambda97/1903597138@5fa9d195
scala> val x = double.compose(sumAppend).apply((List(1,2,3),10))
x: Int = 256
定义compose2
,例如作为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))
}
这将比替代方案更快,因为它不分配元组。用法:
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
如何编写一个 apply 接受多个参数的函数?
这是一个人为的例子:
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
以上给出了类型推断错误?
在这种情况下,您只能编写采用单个参数的函数。所以 sumAppend 必须是接受任何类型的单个参数的函数,并且必须 return Int 的结果(即 _ => Int
)。
您可以将带有两个参数的函数转换为柯里化函数并部分应用该函数,如下所示。
scala> val sumAppend = (l: List[Int], i: Int) => (i :: l).sum
sumAppend: (List[Int], Int) => Int = $$Lambda30/1910012982@44511a58
scala> double.compose(sumAppend.curried.apply(List(1,2,3))).apply(10)
res18: Int = 256
另一种选择是让 sumAppend 接受一个参数,即 List[Int] 和 Int 的元组。
scala> val sumAppend: ((List[Int], Int)) => Int = l => (l._2 :: l._1).sum
sumAppend: ((List[Int], Int)) => Int = $$Lambda97/1903597138@5fa9d195
scala> val x = double.compose(sumAppend).apply((List(1,2,3),10))
x: Int = 256
定义compose2
,例如作为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))
}
这将比替代方案更快,因为它不分配元组。用法:
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