Skip to content

Instantly share code, notes, and snippets.

@oxbowlakes
Created April 24, 2012 10:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oxbowlakes/2478570 to your computer and use it in GitHub Desktop.
Save oxbowlakes/2478570 to your computer and use it in GitHub Desktop.
Lens/State Example to remove repetition
object TradingDays extends App {
import scalaz._
import Scalaz._
case class Trade(sym: String, trader: String, qty: Int)
case class TradingDay(symbols: Map[String, SymDay] = Map.empty)
object TradingDay {
val Syms = Lens[TradingDay, Map[String, SymDay]](_.symbols, (d, s) => d.copy(symbols = s))
}
case class SymDay(symbol: String, traders: Map[String, TraderSymDay] = Map.empty)
object SymDay {
val Traders = Lens[SymDay, Map[String, TraderSymDay]](_.traders, (d, t) => d.copy(traders = t))
}
case class TraderSymDay(trader: String, symbol: String, trades: List[Trade] = Nil)
object TraderSymDay {
val Trades = Lens[TraderSymDay, List[Trade]](_.trades, (d, f) => d.copy(trades = f))
}
import TradingDay._
import SymDay._
import TraderSymDay._
val trades = Trade("VOD", "John", 10) :: Trade("VOD", "Billy-Bob", 10) :: Trade("MSFT", "Billy-Bob", 20) :: Nil
val res = buildDay(trades) //TODO; implement buildDay to reduce repetition
def buildDay(trades: List[Trade]): TradingDays.TradingDay = {
(TradingDay() /: trades) {
(d, trade) =>
def sym = trade.sym
def trader = trade.trader
val upd =
for {
_ <- (Syms member sym).mods(_ orElse SymDay(sym).some)
_ <- (Syms at sym andThen Traders member trader).mods(_ orElse TraderSymDay(trader, sym).some)
_ <- (Syms at sym andThen (Traders at trader) andThen Trades).mods(trade :: _)
x <- init
} yield x
upd ! d
}
}
val expected = TradingDay(Map(
"VOD" -> SymDay("VOD", Map(
"John" -> TraderSymDay("John", "VOD", List(Trade("VOD", "John", 10))),
"Billy-Bob" -> TraderSymDay("Billy-Bob", "VOD", List(Trade("VOD", "Billy-Bob", 10))))),
"MSFT" -> SymDay("MSFT", Map(
"Billy-Bob" -> TraderSymDay("Billy-Bob", "MSFT", List(Trade("MSFT", "Billy-Bob", 20)))
))
))
assert(res == expected, res)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment