在进一步的功能组合中使用组合功能时出错

时间:2019-05-13 01:40:22

标签: scala function-composition

我无法理解为什么我无法使用组合函数并编写新的函数。例如:我有两个函数fg,并从中创建一个组合函数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

1 个答案:

答案 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()