Scala 用多个参数组合函数

Scala 用多个参数组合函数,scala,function-composition,Scala,Function Composition,如果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.c

如果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必须是一个函数,它接受任何类型的单个参数,并且必须返回Int的结果(即
\uu=>Int

您可以将具有两个参数的函数转换为curried函数,并部分应用该函数,如下所示

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
另一种选择是让sumAppend接受一个参数,即List[Int]和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

定义
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
scala>valdouble:Int=>Int=i=>i*i
双精度:Int=>Int=
scala>ValSumAppend:(List[Int],Int)=>Int=(l,i)=>i::l sum
sumpappend:(列表[Int],Int)=>Int=
scala>double.compose2(sumpappend).apply(列表(1,2,3),1)
res5:Int=49