// !LANGUAGE: +ContextReceivers // TARGET_BACKEND: JVM_IR // WITH_STDLIB interface NumberOperations { operator fun Number.plus(other: Number): Number } object DoubleOperations : NumberOperations { override operator fun Number.plus(other: Number) = this.toDouble() + other.toDouble() } data class Matrix(val rows: Int, val columns: Int, val data: Array) { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false other as Matrix if (rows != other.rows) return false if (columns != other.columns) return false if (!data.contentEquals(other.data)) return false return true } override fun hashCode(): Int { var result = rows result = 31 * result + columns result = 31 * result + data.contentHashCode() return result } } fun matrixOf(rows: Int, columns: Int, vararg data: Number): Matrix { assert(rows * columns == data.size) { "Wrong dimentions" } return Matrix(rows, columns, data) } context(NumberOperations) operator fun Matrix.plus(other: Matrix): Matrix { assert(rows == other.rows && columns == other.columns) { "Matrices should have the same dimentions" } return matrixOf(rows, columns, *data.mapIndexed { i, element -> element + other.data[i] }.toTypedArray()) } fun box(): String { val m1 = matrixOf(2, 2, 1, 2, 3, 4) val m2 = matrixOf(2, 2, .4, .3, .2, .1) with(DoubleOperations) { return if (m1 + m2 == matrixOf(2, 2, 1.4, 2.3, 3.2, 4.1)) "OK" else "fail" } }