Note that there are some explanatory texts on larger screens.

plurals
  1. POAvoiding repetition using lenses whilst deep-copying into Map values
    text
    copied!<p>I have an immutable data structure where I have nested values in Maps, like so:</p> <pre><code>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) </code></pre> <p>Separately I have a list of all trades over the day, and I want to generate the <code>TradingDay</code> structure, where</p> <pre><code>case class Trade(sym: String, trader: String, qty: Int) </code></pre> <p>I am trying to figure out how I would update this structure with lenses (see appendix) by folding through my trades:</p> <pre><code>(TradingDay() /: trades) { (trd, d) =&gt; def sym = trd.sym def trader = trd.trader import TradingDay._ import SymDay._ import TraderSymDay._ val mod = for { _ &lt;- (Syms member sym).mods( _ orElse some(SymDay(sym))) _ &lt;- (Syms at sym andThen Traders member trader).mods( _ orElse some(TraderSymDay(trader, sym))) _ &lt;- (Syms at sym andThen (Traders at trader) andThen Trades).mods( trd :: _) x &lt;- init } yield x mod ! d } </code></pre> <p>This works; but I'm wondering whether I could be less repetitive (in terms of adding to a map and then modifying the value at the key of a map. It doesn't seem that much less annoying than the associated deep-copy.</p> <p><strong>Appendix - the lenses</strong></p> <pre><code>object TradingDay { val Syms = Lens[TradingDay, Map[String, SymDay]](_.syms, (d, s) =&gt; d.copy(syms = s)) } object SymDay { val Traders = Lens[SymDay, Map[String, TraderSymDay]](_.traders, (d, t) =&gt; d.copy(traders = t)) } object TraderSymDay { val Trades = Lens[TraderSymDay, List[Trade]](_.trades, (d, f) =&gt; d.copy(trades = f)) } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload