Created
April 24, 2012 10:05
-
-
Save oxbowlakes/2478570 to your computer and use it in GitHub Desktop.
Lens/State Example to remove repetition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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