Отобразить и сложить коллекцию Scala - PullRequest
0 голосов
/ 17 июня 2020

У меня есть fold, который выполняет итерацию по элементам, зависимо изменяет их один за другим и в то же время изменяет их родительский.

В настоящее время я заменяю элементы в их родительских элементах один за другим в fold, их немного, и это не проблема производительности, но мне интересно, есть ли, возможно, лучший способ express это.

case class Behavior(x: Int) {
  def simulate(s: Entity): Behavior = copy(x = x + (if (s.alternate) 2 else 1))
}

case class Entity(alternate: Boolean, behaviors: List[Behavior]) {
  def replaceBehavior(o: Behavior, n: Behavior): Entity = {
    copy(behaviors = behaviors.patch(behaviors.indexOf(o), Seq(n), 1))
  }
  def toggleAlternate: Entity = copy(alternate = !alternate)

  def simulate: Entity = {
    behaviors.foldLeft(this) { (e, b) =>
      e.replaceBehavior(b, b.simulate(e)).toggleAlternate
    }    
  }
}

val entity = Entity(false, List(Behavior(10), Behavior(20), Behavior(30)))

entity.simulate

Есть ли какая-то операция или, возможно, какое-то умное использование scan или что-то подобное, что позволило бы мне выполнить foldLeft и map в зависимости от результата foldLeft за один шаг? (Я бы предпочел ванильную стандартную Scala библиотеку, но возможно и использование функциональных фреймворков).

1 Ответ

2 голосов
/ 17 июня 2020

Складывание (fold, foldLeft, foldRight, ...) обычно превращает некоторые Collection[A] в B.

Вы можете сопоставить A, прежде чем свернуть результат в B - foldMap отображает A => B и предполагает наличие Monoid[B] (это доступно в Cats в Foldable typeclass), поэтому вы должны выполнить преобразование Collection[A] --using f--> Collection[B] --using Monoid[B]--> B (код может оптимизировать его для выполнения задач за один шаг, используя например, foldLeft внутренне).

Изменение порядка операций на обратное - мы fold, а затем map - в общем случае невозможно, потому что нет ничего, что могло бы позволить нам предположить, что после шага fold мы в итоге получится что-то вроде Functor.

В зависимости от вашего конкретного варианта использования c мы можем попробовать использовать foldMap для достижения вашей цели.

...