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.PartialFunctions. f1 is a scala.Function1[Int, Int] aka (Int) => Int and f2 is a scala.Function2[Int, Int, Int] aka (Int, Int) => Int.
