Reputation: 1685
I've just come across a strange problem while trying to overload a function using a partial function :
class Foo {
def bar(pf: PartialFunction[String, Int]): Foo = ???
def bar(zd: Int): Foo = ???
def zed(pf: PartialFunction[String, Int]): Foo = ???
}
...
new Foo()
.bar (0)
.zed { case _ => 1 } // this line is OK
.bar { case _ => 1 } // This line does not compile
I've pasted this code in the REPL, and got a strange error :
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
.bar { case _ => 1 }
^
I've checked on the Internet and find different explanations for this error, but not one talking about overloading. As far as I understand, a PartialFunction is expanded to an anonymous function. So in this case, this would result in something like :
object Test {
new Foo()
.bar (0)
.zed { case _ => 1 }
.bar { (x:String) => x match { case _ => 1 } }
}
But once pasted in the REPL, I get another error :
<console>:17: error: overloaded method value bar with alternatives:
(zd: Int)Foo <and>
(pf: PartialFunction[String,Int])Foo
cannot be applied to (String => Int)
.bar { (x:String) => x match { case _ => 1 } }
^
Which is fine, as there is no signature taking an anonymous function in argument. So what am I missing ? Am I expanding the partial function incorrectly ?
Thank you for any help !
EDIT
I've just found that the problem may come from an ambiguity regarding which method should be called :
object Test {
new Foo()
.bar (0)
.zed { case _ => 1 }
.bar(PartialFunction({case _ => 1})) // This works
}
Secondly, I've found an interesting similar question here
Upvotes: 2
Views: 299
Reputation: 39577
As retronym says in the places you linked, it's not a partial function, but a pattern matching anonymous function, which could be either a PartialFunction
or a Function
depending on what's expected, and the issue is that it can't infer types because typechecking the arg for purposes of overloading happens without an "expected type". The "shape" test lets the function literal work.
scala> object X { def f(i: Int) = ??? ; def f(g: Int => Int) = ??? }
defined object X
scala> X.f { case i => 2 * i }
<console>:13: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
X.f { case i => 2 * i }
^
scala> X.f(i => 2 * i)
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
at X$.f(<console>:11)
... 28 elided
scala> X.f({ case i => 2 * i }: Int => Int)
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
at X$.f(<console>:11)
... 28 elided
Upvotes: 2
Reputation: 1685
Here's the explication of this issue. It seems that the compiler is not able to resolve the type or pattern matching anonymous functions. Simply because their "shape" cannot be resolved. In other words, overloading cannot be used with PartialFunctions.
Upvotes: 0