我无法理解为什么我无法使用组合函数并编写新的函数。例如:我有两个函数f
和g
,并从中创建一个组合函数composed1
。我试图将组合与第四种功能lastOne
组合在一起,但失败了。
我要创建两个组合函数,第二个组合函数是否可以重用第一个组合函数?
scala> def f(x: Int)(y: Int) = {
| x + y
| }
f: (x: Int)(y: Int)Int
scala> def g(a: Int)(b: Int) = {
| a + b
| }
g: (a: Int)(b: Int)Int
scala> def composed1(a: Int, b: Int) = {
| f(a) _ andThen g(b)
| }
composed1: (a: Int, b: Int)Int => Int
scala> composed1(2, 2)(5)
res1: Int = 9
scala> def lastOne(l: Int)(x: Int) = {
| l + x
| }
lastOne: (l: Int)(x: Int)Int
scala> def composed2(a: Int, b: Int, c: Int) = {
| composed1(a, b) _ andThen lastOne(c)
| }
<console>:14: error: _ must follow method; cannot follow Int => Int
composed1(a, b) _ andThen lastOne(c)
^
<console>:14: error: missing argument list for method lastOne
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `lastOne _` or `lastOne(_)(_)` instead of `lastOne`.
composed1(a, b) _ andThen lastOne(c)
当我将它们全部一起使用时,它会起作用
scala> def test(x: Int, y: Int, z: Int) = {
| f(x) _ andThen g(y) _ andThen lastOne(z)
| }
test: (x: Int, y: Int, z: Int)Int => Int
scala> test(2, 2, 4)(5)
res9: Int = 13
答案 0 :(得分:3)
f()()
和g()()
是方法。 Methods are not functions,但是方法可以通过“ eta expansion”提升为功能。一种方法是使用下划线代替传递的参数。
andThen()
是Function
trait上的一种方法,该方法将一个函数作为参数并返回一个新函数。似乎您也可以使用方法作为传递的参数,但是它正在默默地提升为Function
状态。
因此composed1()
看起来像一个方法,但实际上是一个Function
,因为这就是andThen()
返回的内容,并且您不能将下划线eta扩展应用于{{1} }。它仅适用于方法。
作为实验,将Function
变成执行相同操作的f()()
...
Function
...现在def f :Int => Int => Int = (x: Int) => (y: Int) => x + y
无法编译。
因此,既然我们知道composed1()
是composed1()
,那么我们如何从Function
得到我们想要的东西?简单。跳过下划线。
composed2()