Я экспериментирую с зависимыми от пути типами. В моем простом примере я использую объект Currency, чтобы гарантировать, что денежные расчеты могут быть выполнены только на деньги той же валюты.Восстановить связь между зависимым от пути типом и его родителем во время выполнения?
// Simple currency class
case class Currency(code: String, name: String, symbol: String) {
// Money amounts in this currency
// Operations are only supported on money of the same currency
case class Money(amount: BigDecimal) {
override def toString: String = s"$code $amount"
val currency: Currency.this.type = Currency.this
def +(rhs: Money): Money = Money(amount + rhs.amount)
def -(rhs: Money): Money = Money(amount - rhs.amount)
}
}
Использование вышеуказанного класса простых калорий в реплике осуществляется вперед.
val e1 = Euro.Money(5)
val e2 = Euro.Money(9)
e1 + e2 // Compiles fine
val d1 = Dollar.Money(6)
d1 + e2 // Doesn't compile as expected
Это просто, потому что компилятор может легко доказать, что e1 и e2 имеют общую валюту. Однако доказать, что денежные экземпляры имеют общую валюту, намного сложнее, когда я прочитал список денежных сумм из файла или базы данных. Например, я не вижу, как реализовать функцию сортировки ниже.
trait CurrencyAndMonies {
val currency: Currency
val monies: List[currency.Money]
}
// Take a list of money in different currencies and group them by currency
// so their shared Currency type is available to static type checking
// in further calculations
def collate(Seq[Currency#Money]): List[CurrencyAndMonies] = ???
Возможно ли отсортировать денежные средства на основе валюты и восстановить связь между ними? И если да, то как? Я не против изменения подписи или способа чтения денег из базы данных.
Спасибо за ваш ответ. Я думаю, вы правы, что мне придется бросить его, что очень жаль. Я смотрю на самый опрятный способ его литья в данный момент (возможно, поместив его за образец, соответствующий безопасности). – iain