Scala, currying and overloading

2020-02-10 03:41发布

问题:

Say you have the following:

foo(x: String)(y: Int): Int
foo(x: String)(y: Double): Int

Scala does not allow such expression. As far as I can see, the reason for this is that foo("asdf") does not have a well defined type (it's either Int => Int or Double => Int).

Is there a reason why such "polytyped" functions should not be allowed?

回答1:

Overloading resolution in Scala takes only the first parameter list into account. That's why alternatives must differ already in this list. There's a good reason for this: We can then use the resolved function's type to infer the type of subsequent arguments. This enables idioms like:

xs.corresponds(ys) { (x, y) => x < y }

Note that here we need to know the type of corresponds in order to infer the types of x and y. It would be a shame to have this break down when corresponds is overloaded.



回答2:

This isn't the first time this has been asked: it was asked back in 2009. Unfortunately Martin didn't explicitly state what the issues were, other than that it would require a fairly extensive spec change on how overloading works. I've looked at the spec and it's not clear to me where the core issues lie, but I'm not skilled enough in the spec to give a definitive answer either way.



回答3:

A simple workaround is to use an anonymous object:

def foo(x: String) = new {
  def apply(y: Int): Int
  def apply(y: Double): Int
}