2013-03-19 5 views
2

Я написал функцию, как это в Scala:Scala Хвостовая рекурсия Оптимизация на короткозамкнутым операций булевой

def isSorted[T](list : List[T])(compare : (T, T) => Boolean) : Boolean = { 
    list match { 
     case Nil => true 
     case x :: Nil => true 
     case x :: rest => !compare(rest.head, x) && isSorted(rest)(compare) 
    } 
} 

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

+4

вот что ['@ annotation.tailrec'] (http://stackoverflow.com/questions/3114142/what-is-the-scala- аннотация для обеспечения-хвост-рекурсивная-функция-оптимизирована) для –

+0

Прохладный. Кажется, он оптимизирован. Благодаря! –

+3

Просто, чтобы быть понятным, '@ tailrec' не волшебным образом делает метод хвостовым рекурсивным, это делает его ошибкой, чтобы он не был хвостовым рекурсивным. –

ответ

3

Итак, как говорит @omnomnom, вы можете проверить, не является ли что-то TCO-ed, добавив аннотацию @tailrec к методу. Компилятор выдаст ошибку, если не сможет ее выбрать.

Мы можем проверить это с помощью простого примера:

@tailrec 
def fact(n : Int) : Int = fact(n - 1) * 2 

бомбы компилятор из-за ошибки:

test.scala:6: error: could not optimize @tailrec annotated method fact: it contains a recursive call not in tail position

Попытка это на вашей программе, однако, ответ ... да! Поэтому, по-видимому, компилятор с удовольствием оптимизирует ваш хвост: -)

+3

Интересное определение 'факт' у вас там есть :) –