breandan
02/06/2021, 8:27 PMIaroslav Postovalov
02/07/2021, 5:42 AMobject A { fun add(d1: Double, d2: Double) }
operator fun (A, Double).plus(o: Double) = this@A.add(this@Double, o)
breandan
02/07/2021, 6:02 AMIaroslav Postovalov
02/07/2021, 6:05 AMRealField { 0f + 0.1 } // Double(0.1)
altavir
02/07/2021, 6:25 AMbreandan
02/07/2021, 6:25 AMfun main() {
object: RealField, OtherAlgebra{}.run {
println(1.d + 1.0)
someOp(1.d, 1.0)
}
}
val Number.d: KDbl
get() = KDbl(toDouble())
interface RealField {
fun add(d1: KDbl, d2: KDbl) = KDbl(d1.v + d2.v)
//...
}
interface OtherAlgebra {
fun someOp(d1: KDbl, d: Double) = KDbl(d1.v / d)
}
class KDbl(val v: Double) {
operator fun plus(d: Double) = KDbl(v + d)
}
breandan
02/07/2021, 6:27 AMKdbl
doesn't need to be an interface, but the algebras do in order to use multiple inheritancebreandan
02/07/2021, 6:37 AM(A, Double).
syntax provides that isn't already possible with interfaces (but it could be I'm missing something obvious)altavir
02/07/2021, 6:41 AMoperator fun [SomethingField, FieldElement].plus(other: FieldElement): FieldElement = add(this@FieldElement, other)
I am using old Keep-176 notation instead of the new with
sinch I am not sure it will work properly. We do not use new-types wrappings here and instead move the dispatch from types to scopes. As a bonus we can operate on initial types without wrapping them. In this example the benefit is purely cosmetice because operators require receiver and we can't define them without either bringin operator fun inside the algebra scope or multi-receivers. But there are other applications as well.altavir
02/07/2021, 6:45 AMbreandan
02/07/2021, 7:01 AMaltavir
02/07/2021, 7:08 AM