object Example {
object Converter {
var exchangeRate = Map(
"USD" -> Map("USD" -> 1.0, "EUR" -> 0.7596,
"JPY" -> 1.211, "CHF" -> 1.223),
"EUR" -> Map("USD" -> 1.316, "EUR" -> 1.0,
"JPY" -> 1.594, "CHF" -> 1.623),
"JPY" -> Map("USD" -> 0.8257, "EUR" -> 0.6272,
"JPY" -> 1.0, "CHF" -> 1.018),
"CHF" -> Map("USD" -> 0.8108, "EUR" -> 0.6160,
"JPY" -> 0.982, "CHF" -> 1.0))
}
abstract class CurrencyZone {
type Currency <: AbstractCurrency
val currencyUnit: Currency
def make(x: Long): Currency
abstract class AbstractCurrency {
val amount: Long
def designation: String
def +(that: Currency): Currency = {
make(this.amount + that.amount)
}
def *(x: Double): Currency = {
make((this.amount * x).toLong)
}
def -(that: Currency) = {
make(this.amount - that.amount)
}
def /(that: Double) = make((this.amount / that).toLong)
def from(other: CurrencyZone#AbstractCurrency): Currency = {
val e = Converter.exchangeRate(other.designation)(designation)
make(math.round(other.amount.toDouble * e))
}
override def toString = {
val dollars = amount / currencyUnit.amount
val cents = amount % currencyUnit.amount
"%d %s %d".format(dollars, designation, cents)
}
}
}
object US extends CurrencyZone {
abstract class Dollar extends AbstractCurrency {
def designation = "USD"
}
type Currency = Dollar
def make(x: Long) = new Dollar {
val amount = x
}
val currencyUnit = make(100)
}
object EU extends CurrencyZone {
abstract class Euro extends AbstractCurrency {
def designation = "EUR"
}
override type Currency = Euro
override def make(x: Long): EU.Currency = new Euro {
override val amount: Long = x
}
override val currencyUnit: EU.Currency = make(100)
}
}
object Test {
import Example._
val dollar = US.currencyUnit
val euro = EU.currencyUnit
val x = US.make(120)
x + US.make(110) // $2.30
x * 2.0 // $2.40
val y = EU.make(120)
y + EU.make(110) // €2.30
y * 2.0 // €2.40
US.make(100) + x.from(EU.make(100)) // $2.32
dollar + dollar.from(euro)
US.make(200) + dollar.from(EU.make(200)) // around $4.64
}
Friday, October 16, 2015
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment