Ошибки «один за другим» предполагают, что вы пытаетесь поместить исходный список в однозначное соответствие со скользящим списком, но происходит нечто странное, поскольку в скользящем списке меньше элементов.
Формулировка задачи для вашего примера может быть примерно сформулирована следующим образом: «Прописные буквы каждого символа, если он (a) является первым символом или (b) следует за буквенным символом».Как указывает Оуэн, первый символ - это особый случай, и любая абстракция должна это учитывать.Вот возможность,
def slidingPairMap[A, B](s: List[A], f1: A => B, f2: (A, A) => B): List[B] = s match {
case Nil => Nil
case x :: _ => f1(x) +: s.sliding(2).toList.map { case List(x, y) => f2(x, y) }
}
(не лучшая реализация, но вы поняли идею).Это обобщает на скользящие тройки, с ошибками в два раза и так далее.Тип slidingPairMap
дает понять, что выполняется специальный корпус.
Эквивалентная подпись может быть
def slidingPairMap[A, B](s: List[A], f: Either[A, (A, A)] => B): List[B]
Тогда f
может использовать сопоставление с образцом, чтобы выяснить, работает ли онс первым элементом или с последующим.
Или, как говорит Оуэн в комментариях, почему бы не создать модифицированный метод sliding
, который дает информацию о том, является ли элемент первым или нет,
def slidingPairs[A](s: List[A]): List[Either[A, (A, A)]]
Я полагаю, что эта последняя идея изоморфна тому, что Дебилски предлагает в комментариях: добавьте начало списка с помощью None, оберните все существующие элементы с помощью Some
, а затем вызовите sliding
.