val f1 = (x: Int) => x match {
case x1 => x * 2
}
val f2 = (x: Int, y: Int) => (x, y) match {
case (x1, y1) => x1 y1
}
val f3 = f1.compose(f2)
Expecting f3 to be a partial function from (Int, Int) => Int but I get the following error
Found: (f2 : (Int, Int) => Int)
Required: Any => Int
CodePudding user response:
As the documentation suggests, compose
specifically composes two instances of Function1
, that is two instances of a unary function.
If you want to keep your code as is, the way to do this is
f1 andThen f2.curried
If you look at the documentation closely
compose
returns a new function f s.t. f(x) == apply(g(x))
andThen
returns a new function f s.t. f(x) == g(apply(x))
Note the difference in order of application. Yes, I know the naming is rather is confusing.
Edit: It is confusing which way you want these to apply. The other way around is provided in Jorg's answer.
CodePudding user response:
Both scala.Function1.compose
and scala.PartialFunction.compose
only take functions as parameters which have a single parameter. But f2
has two parameters, therefore, it is not type-compatible with the parameter type of compose
.
You can convert f2
to a single-parameter function which takes its parameters as a scala.Tuple
using the scala.Function2.tupled
method:
val f3 = f1.compose(f2.tupled)
Note: f3
is now a Function1[Tuple2[Int, Int], Int]
aka ((Int, Int)) => Int
, i.e. it needs to be applied like this:
f3((2, 3))
To turn it into a Function2[Int, Int, Int]
aka (Int, Int) => Int
, you can use the scala.Function.untupled
method:
val f4 = Function.untupled(f3)
Also note that neither f1
nor f2
are scala.PartialFunction
s. f1
is a scala.Function1[Int, Int]
aka (Int) => Int
and f2
is a scala.Function2[Int, Int, Int]
aka (Int, Int) => Int
.