I'll give an example/motivation for what I'm trying to do.
Imagine I have a Money case class, and a way to convert it's value from one currency to another:
case class Money(currency: String, amount: BigDecimal) {
def convert(date: LocalDate)(using cc: CurrencyConverter): Money = {...}
}
The CurrencyConverter
is a Map with daily exchange rates between currency, so that I can use the convert
method to go for example from something like Money("EUR", BigDecimal(100))
to Money("USD", BigDecimal(114.13))
.
Then, I have a lot of different case classes with one or more Money fields. For example:
case class House(date: LocalDate, price: Money, city: String)
case class MarketData(
exchange: String,
ticker: String,
date: LocalDate,
closingPrice: Money,
openPrice: Money
)
Since I could data where the data is in a lot of different currencies, for example
val house1 = House(LocalDate.parse("2010-01-01"), Money("USD", BigDecimal(400000)), "San Francisco")
val house2 = House(LocalDate.parse("2018-01-01"), Money("EUR", BigDecimal(200000)), "Rome")
it would be useful to give each case class a method convertCurrency
to allow them to convert their Money fields to a common currency.
I could define a trait with an abstract method and manually override it inside each case class definition, like so:
trait MoneyConverter[A] {
def convertCurrency(using cc: CurrencyConverter): A
}
case class House(date: LocalDate, price: Money, city: String)
extends MoneyConverter[House] {
override def convertCurrency(using cc: CurrencyConverter): House =
House(date, price.convert(date), city)
}
case class MarketData(
exchange: String,
ticker: String,
date: LocalDate,
closingPrice: Money,
openPrice: Money
) extends MoneyConverter[MarketData] {
override def convertCurrency(using cc: CurrencyConverter): MarketData =
MarketData(
exchange,
ticker,
date,
closingPrice.convert(date),
openPrice.convert(date)
)
}
but it seams like I'm repeating myself. Each method is doing basically the same: it is applying the convert method to each Money
field, and leaving the other fields as they were.
So my question is: Is there a way for me to describe this behavior for a generic class A
, so that I can then just extend the MoneyConverter
trait, without having to manually override the convertCurrency
method for each case class?
Aucun commentaire:
Enregistrer un commentaire