Подтвердить что ты не робот

Можно ли расширить компилятор Scala для вывода возвращаемых типов рекурсивных методов?

Компилятор Scala в настоящее время не может выводить возвращаемые типы рекурсивных методов, как в следующем коде

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

Есть ли какая-либо амбициозность в приведенном выше утверждении? (т.е. возможен ли какой-либо другой тип, кроме Int?)

Я могу представить, что в более сложном примере будет сложно вывести тип.

Можно ли дополнительно охарактеризовать случаи рекурсивных методов, где мы можем (не) выводить типы?

[EDIT:] Компилятор достаточно умен, чтобы понять, что 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
4b9b3361

Ответ 1

Если ваш рекурсивный вызов всегда находится в последней позиции, т.е. его значение никогда не используется и возвращается только, должно быть возможно определить тип как общий супертип всех других ветвей.

Однако в ситуации вроде

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

вы не знаете тип foo(i - 1) + 1 (или понимаете операцию +, потому что это фактически метод на foo - все становится сложнее в присутствии объектов), не зная, что foo, Итак, снова вы двигаетесь по кругу.

Ответ 2

Вам понадобится алгоритм унификации, намного более мощный, чем 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 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 type
error