I find an "Argument type mismatch" error in multiply function and don't know how to fix it. The code is:
abstract class Semigroup<T1> {
abstract val one: SemigroupElement<T1>
abstract fun builder(x: T1): SemigroupElement<T1>
abstract val binOp: (SemigroupElement<T1>, SemigroupElement<T1>) -> SemigroupElement<T1>
abstract inner class SemigroupElement<T1> {
fun multiply(other: SemigroupElement<T1>) = binOp(this, other) // Argument type mismatch
abstract val value: T1
}
}
When you name all type parameters the same (T1
) it becomes confusing.
Let's first rename the type parameter of class Semigroup
from T1
to T
and the type parameter of class SemigroupElement
from T1
to E
.
Then you have the following code:
abstract class Semigroup<T> {
abstract val one : SemigroupElement<T>
abstract fun builder(x: T): SemigroupElement<T>
abstract val binOp: (SemigroupElement<T>, SemigroupElement<T>) -> SemigroupElement<T>
abstract inner class SemigroupElement<E> {
fun multiply(other: SemigroupElement<E>) = binOp(this, other) // Argument type mismatch
abstract val value: E
}
}
And now it becomes clear why this doesn't work: The abstract binOp
requires two SemigroupElement<T>
, but you provide it with two SemigroupElement<E>
. Since T
and E
are not related in any way the compiler protests with the error "Type mismatch."
It's not clear what you want to achieve, but it looks like you may not even need a type parameter for SemigroupElement
at all. Since SemigroupElement is an inner1 class of the (outer) class Semigroup it can only exist with an instance of Semigroup. Therefore you can access the outer class' type parameter T
and let value
be of that type:
abstract class Semigroup<T> {
abstract val one: SemigroupElement
abstract fun builder(x: T): SemigroupElement
abstract val binOp: (SemigroupElement, SemigroupElement) -> SemigroupElement
abstract inner class SemigroupElement {
fun multiply(other: SemigroupElement) = binOp(this, other) // This compiles just fine now
abstract val value: T
}
}
1: Not nested, as your question title suggests; a nested class wouldn't have the inner
modifier, allowing an instance of it even without an instance of the outer class. Here, you have an inner class, not a nested class.
For more see the documentation about Nested and inner classes.