Skip to content

Instantly share code, notes, and snippets.

@dimitrisli
Created February 25, 2015 03:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dimitrisli/e85ee179e7f9358be5d1 to your computer and use it in GitHub Desktop.
Save dimitrisli/e85ee179e7f9358be5d1 to your computer and use it in GitHub Desktop.
ScalaForexRatesDSL
object ScalaForexRatesDSL {
implicit class ccy2money(ccy :Symbol) {
def apply(amount: BigDecimal) = Money(amount, ccy)
}
}
case class FromToCcy(ccyFrom: Symbol, ccyTo: Symbol)
case class Money(amount:BigDecimal, ccy:Symbol) {
def + (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
if(ccy == other.ccy) Money(amount + other.amount, ccy) else {
val convertedOther = convertedOtherMoney(other)
Money(amount + convertedOther.amount, ccy)
}
def - (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
if(ccy == other.ccy) Money(amount - other.amount, ccy) else {
val convertedOther = convertedOtherMoney(other)
Money(amount - convertedOther.amount, ccy)
}
def * (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
if(ccy == other.ccy) Money(amount * other.amount, ccy) else {
val convertedOther = convertedOtherMoney(other)
Money(amount * convertedOther.amount, ccy)
}
def / (other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
if(ccy == other.ccy) Money(amount / other.amount, ccy) else {
val convertedOther = convertedOtherMoney(other)
Money(amount / convertedOther.amount, ccy)
}
private def convertedOtherMoney(other: Money)(implicit rates: Map[FromToCcy, BigDecimal]): Money = {
val rate = rates.get(FromToCcy(other.ccy, ccy)).getOrElse(1 / rates.get(FromToCcy(ccy, other.ccy)).get)
Money(other.amount * rate, ccy)
}
def in(ccy: Symbol)(implicit rates: Map[FromToCcy, BigDecimal]): Money =
if (this.ccy == ccy) this else {
val rate = rates.get(FromToCcy(this.ccy, ccy)).getOrElse(1 / rates.get(FromToCcy(ccy, this.ccy)).get)
Money(amount * rate, ccy)
}
override def toString = amount + " " + ccy.name
}
object Main extends App {
import ScalaForexRatesDSL._
implicit val rates = Map((FromToCcy('EUR, 'USD) -> BigDecimal(1.13)))
print( 'USD(100) + 'EUR(200) in 'EUR )
}
@mslinn
Copy link

mslinn commented Mar 11, 2015

Perhaps the Money case class should receive the rates implicit, instead of each operator? It seems likely that you would like a consistent exchange rate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment