2011-08-24 35 views
14

假设你有以下几点:斯卡拉,柯里和重载

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

斯卡拉不允许这样的表达。据我所知,其原因是foo(“asdf”)没有明确定义的类型(它是Int => Int或Double => Int)。

为什么不应该允许这种“多种”功能的原因是什么?

+0

https://issues.scala-lang.org/browse/SI-2628 – Bradford

+0

Scala允许你定义这对重载方法,但是它的任何调用都是不明确的,由Martin下面概述的原因。相关:http://stackoverflow.com/questions/2510108/why-avoid-method-overloading – retronym

回答

19

Scala中的重载分辨率只考虑了第一个参数列表。这就是为什么替代品必须在此列表中有所不同。有一个很好的理由:然后我们可以使用已解析函数的类型来推断后续参数的类型。这使得像成语:

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

注意,这里我们需要知道的corresponds类型,以推断类型的xy。如果corresponds过载,让这种情况发生,这将是一件耻辱。

+0

感谢您的回答。作为后续工作,根据对应的重载版本的范围(类似于implicits的工作方式)并且仅仅根据这些关系来决定可能的类型是否有可能分配给x和y的列表只有在必须时才会键入? 或者这会违背静态类型的想法吗? –

+0

@Martin Odersky你能看到http://stackoverflow.com/q/7291168谢谢! –

+2

考虑可能类型列表的任何方法都有可能导致类型检查时间呈指数级增长。这就是为什么Scala在其类型推断算法中通常不这么做的原因。 –

2

这不是第一次询问:it was asked back in 2009。不幸的是,马丁并没有明确说明问题是什么,除了需要对超载的工作方式进行相当广泛的规范改变之外。我已经看过这个规范,但是我不清楚核心问题在哪里,但是我没有足够的技巧来给出明确的答案。

+1

这是一个稍微不同的问题。在你连接的问题中,你有两个函数,它们只会在返回类型中有所不同('foo(x:Bar):Unit' vs.'foo(x:Bar)):Function1 [Bar => Baz,Unit] ')如果我的推理是正确的(仍然不完全相信...) – Dirk

+0

我不明白为什么_issue_是不同的。问题出现的条件可能不同,但我认为问题是相同的。我尝试了各种操作,但错误从未改变。我认为,重载是很早就完成的,或者优先于“x”。 –

+0

我不确定这是一样的。在你链接的scala问题中,有两个函数是有意义的,因为foo()和foo()_是不同的,而在当前情况下,没有不同的方式来表达两个可能的foo() _ 功能。 潜在的原因可能是一样的,但我不相信。实际上,我认为这也是德克的观点。 –