Избегайте повторений с помощью линз при глубоком копировании -в значения карты

У меня есть неизменяемая структура данных, где у меня есть вложенные значения в Картах, вот так:

case class TradingDay(syms: Map[String, SymDay] = Map.empty)
case class SymDay(sym: String, traders: Map[String, TraderSymDay] = Map.empty)
case class TraderSymDay(trader: String, sym: String, trades: List[Trade] = Nil)

Отдельно у меня есть список всех сделок в течение дня, и я хочу сгенерировать структуру TradingDay, где

case class Trade(sym: String, trader: String, qty: Int)

я пытаюсь понять, как обновить эту структуру с помощью линз (см. приложение ), свернув мои сделки:

(TradingDay() /: trades) { (trd, d) =>
  def sym = trd.sym
  def trader = trd.trader
  import TradingDay._
  import SymDay._
  import TraderSymDay._
  val mod =
    for {
      _ <- (Syms member sym).mods(
             _ orElse some(SymDay(sym)))
      _ <- (Syms at sym andThen Traders member trader).mods(
             _ orElse some(TraderSymDay(trader, sym)))
      _ <- (Syms at sym andThen (Traders at trader) andThen Trades).mods(
             trd :: _)
      x <- init
    } yield x
  mod ! d
}

Это работает; но мне интересно, могу ли я быть менее повторяющимся (с точки зрения добавления к карте, а затем изменения значения ключа карты. Это не кажется менее раздражающим, чем соответствующая глубокая копия -.

Приложение -Линзы

object TradingDay {
  val Syms = Lens[TradingDay, Map[String, SymDay]](_.syms, (d, s) => d.copy(syms = s))
}

object SymDay {
  val Traders = Lens[SymDay, Map[String, TraderSymDay]](_.traders, (d, t) => d.copy(traders = t))
}

object TraderSymDay  {
   val Trades = Lens[TraderSymDay, List[Trade]](_.trades, (d, f) => d.copy(trades = f))
}
14
задан oxbow_lakes 20 April 2012 в 14:16
поделиться