Идиоматическая конструкция для проверки того, упорядочена ли коллекция

С намерением изучить и продолжить этот вопрос , мне по-прежнему любопытны идиоматические альтернативы явной рекурсии для алгоритма, который проверяет, упорядочен ли список (или коллекция) . (Я стараюсь упростить здесь задачу, используя оператор для сравнения и тип 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

Альтернативный алгоритм, использующий свертку:

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 элементов списка, даже если он может остановиться раньше после нахождения первого вышедший из строя элемент. Есть ли способ «остановить» фолд и, следовательно, сделать это лучшим решением?

Какие-нибудь другие (элегантные) альтернативы?

37
задан Community 23 May 2017 в 12:32
поделиться