С целью изучения и дальнейшего использования этого question я по-прежнему интересуюсь идиоматическими альтернативами явной рекурсии для алгоритма, который проверяет, является ли список (или сбор). (Я делаю здесь простые вещи, используя оператор для сравнения и тип Int как, я хотел бы взглянуть на алгоритм, прежде чем вникать в его дженерики)
Базовая рекурсивная версия будет (по @Luigi Plinge):
def isOrdered(l:List[Int]): Boolean = l match {
case Nil => true
case x :: Nil => true
case x :: xs => x <= xs.head && isOrdered(xs)
}
Плохой исполняющий идиоматический путь:
def isOrdered(l: List[Int]) = l == l.sorted
Альтернативный алгоритм с использованием fold:
def isOrdered(l: List[Int]) =
l.foldLeft((true, None:Option[Int]))((x,y) =>
(x._1 && x._2.map(_ <= y).getOrElse(true), Some(y)))._1
У него есть недостаток, который он будет сравнивать для всех n элементов списка, даже если он мог остановиться раньше, после обнаружения первого элемента вне порядка. Есть ли способ "остановить" сгиб и, следовательно, сделать это лучшим решением?
Любые другие (изящные) альтернативы?