Заглавие гласит все, действительно; итерация по коллекции при сохранении состояния между циклами и завершающей итерации на основе условия завершения в дополнение к простому исчерпанию элементов может быть наиболее распространенной схемой для выполнения чего-либо в императивном программировании. Мне кажется, однако, как это что-то функциональные gentleprogrammers договорились не говорить об этом, или по крайней мере, я никогда не сталкивался с идиомы для него или полу-стандартизировано именем, например, как с map
, fold
, reduce
и т.д.Есть ли концепция «сбрасывать с перерывом» или «найти с аккумулятором» в функциональном программировании?
Я часто использую последующий код в scala:
implicit class FoldWhile[T](private val items :Iterable[T]) extends AnyVal {
def foldWhile[A](start :A)(until :A=>Boolean)(op :(A, T)=>A) :A = {
if (until(start)) start
else {
var accumulator = start
items.find{ e => accumulator = op(accumulator, e); until(accumulator) }
accumulator
}
}
}
Но это уродливо. Всякий раз, когда я пытаюсь более декларативный подход, я прихожу с еще дольше и почти наверняка более медленным кодом, сродни:
Iterator.iterate((start, items.iterator)){
case (acc, i) if until(acc) => (acc, i)
case (acc, i) if i.hasNext => (op(acc, i.next()), i)
case x => x
}.dropWhile {
case (acc, i) => !until(acc) && i.hasNext
}.next()._1
(Более функциональный вариант будет использовать List
с или Stream
с, но итераторы имеют, возможно, меньшую нагрузку, чем преобразование items
- Stream
, так как для реализации по умолчанию для последнего используется итератор в любом случае).
Мои вопросы:
1) Имеет ли это понятие имя в функциональном программировании, и если да, то это шаблон, связанный с его реализацией?
2) Что было бы лучшим (то есть кратким, общим, ленивым и с наименьшим издержком) способом реализовать его в scala?
Я никогда не понимал, почему у этого нет стандартной реализации. Да. хвостовая рекурсия - это способ сделать это, но это немного уродливо (и требует вспомогательной функции, для которой нужно найти имя, которое всегда кажется немного запахом кода для меня). .mapUntil' и 'foldLeftUntil' и т. д., мне кажутся полезными ... –