是否可以扩展Scala编译器以推断返回类型的递归方法?

时间:2011-10-11 18:57:33

标签: scala

Scala编译器当前无法推断递归方法的返回类型,如下面的代码

def foo(i:Int) = if (i > 0) foo (i-1) else 0

上述声明中是否存在任何矛盾? (即,Int可能以外的任何类型吗?)

我可以想象,在更复杂的例子中,很难推断出类型。

是否有可能进一步描述递归方法的情况,我们可以(不)推断出类型?

[编辑:]编译器足够智能,可以发现String不正确。

scala> def foo(i:Int):String = if (i > 0) foo (i-1) else 0
<console>:5: error: type mismatch;
found   : Int(0)
required: String

2 个答案:

答案 0 :(得分:6)

如果你的递归调用总是在最后一个位置,即它的值从未被使用过并且只返回,那么应该可以将类型确定为所有其他分支的公共超类型。

然而,在像

这样的情况下
def foo(i: Int) = if (i > 0) foo(i - 1) + 1 else 0

你不会知道foo(i - 1) + 1的类型(或理解操作+,因为它实际上是foo上的方法 - 在存在对象时事情变得越来越复杂)知道foo是什么。所以,你又一次在圈子里走来走去。

答案 1 :(得分:3)

您需要一个比Scala提供的功能更强大的统一算法。 Scala从左到右,从上到下进行类型检查。所以推论会有点像这样:

What is the type of expression "if (i > 0) foo(i - 1) + 1 else 0"?
Unify "foo(i - 1) + 1" and "0"
What is the type of "foo(i - 1) + 1"?
What is the type of "foo(i - 1)"
What is "foo"?
foo is the current definition, so we don't know it's type
error

如果你以if的方式完成了另一种方式:

What is the type of expression "if (i <= 0) 0 else foo(i - 1) + 1 "?
Unify "0" and "foo(i - 1) + 1"
What is the type of "0"?
"0" <: Int >: Nothing
What is the type of "foo(i - 1) + 1"?
What is the type of "foo(i - 1)"
What is "foo"?
foo is the current definition, so we don't know it's type
error