This currently compiles:
class Test {
def foo(f: PartialFunction[(Int, Int), Int]) = ???
foo((a, b) => 1)
}
I don't think we should apply auto-tupling in this case though.
I personally think this behavior is intuitive. A total function is a partial function that happens to cover all inputs. I wish Function was a subtype of PartialFunction instead of the other way around, it's one of the biggest warts in the standard library in my opinion.
The documentation says:
Generally, a function value with n > 1 parameters is converted to a pattern-matching closure using case if the expected type is a unary function type of the form ((T_1, ..., T_n)) => U
This actually works because PartialFunction[(T_1, ..., T_n), U] is a subtype of ((T_1, ..., T_n)) => U:
class Test {
trait Foo extends Function1[(Int, Int), Int]
def foo(f: Foo) = ???
foo((a, b) => 1) // OK
}
But then you can write something like:
class Test {
trait Foo extends Function1[(Int, Int), Int] {
def bar: Int
}
def foo(f: Foo) = f.bar
foo((a, b) => 1)
}
and get nonsensical errors:
-- [E081] Syntax Error: tests/allan/Test.scala:6:7 -----------------------------
6 | foo((a, b) => 1)
| ^
| missing parameter type for parameter a, expected = ?
longer explanation available when compiling with `-explain`
-- [E081] Syntax Error: tests/allan/Test.scala:6:10 ----------------------------
6 | foo((a, b) => 1)
| ^
| missing parameter type for parameter b, expected = ?
One more puzzle with partial functions:
class Foo extends Product2[Int, Int] {
def _1 = 1
def _2 = 2
def canEqual(that: Any) = ???
}
val xs: List[Product2[Int, Int]] = List(new Foo)
xs.collect { case (x, y) => x + y } // List()
xs.collect((x, y) => x + y) // List(3)
We decided to disallow auto-tupling for partial functions
I am not sure anymore what the right way is. Anyway, I don't think we should act on this until we have sorted out PartialFunctions. And once we did that, the answer to the question of auto-tupling or not is probably "whatever fits best".
Most helpful comment
I personally think this behavior is intuitive. A total function is a partial function that happens to cover all inputs. I wish
Functionwas a subtype ofPartialFunctioninstead of the other way around, it's one of the biggest warts in the standard library in my opinion.