Чтобы преодолеть это сообщение об ошибке, вы должны использовать F-ограниченный полиморфизм .
Ваш код будет выглядеть примерно так:
trait Abst[F <: Abst[F, T], T]{ self: F =>
def met1(p: T): String = p.toString
def met2(p: T, f: Double => F): String = {
val v = f(1.0)
v.met1(p)
}
}
case class Param(a:Int)
class MyClass(x: Double) extends Abst[MyClass, Param] {
val s = met2(Param(1), (d: Double) => new MyClass(d))
}
Объяснение:
Использование self: F =>
внутри определения черты или класса ограничивает значение this
.Таким образом, ваш код не скомпилируется, если this
не относится к типу F
.
Мы используем ограничение циклического типа F
: F <: Abst[F, T]
.Хотя это противоречит интуиции, компилятор не возражает против этого.
В реализации MyClass
мы затем расширяем MyClass
на Abst[MyClass, Param]
, что, в свою очередь, удовлетворяет F <: Abst[F, T]
.
Теперьвы можете использовать F
в качестве типа возврата функции в Abst
и иметь MyClass
return MyClass
в реализации.
Вы можете подумать, что это решение уродливо, и если выделайте, тогда вы правы.
Вместо использования F-ограниченного полиморфизма всегда рекомендуется использовать классов типов для ad-hoc-полиморфизма .
Более подробную информацию вы найдете по ссылке, которую я предоставил ранее.
Действительно, прочитайте ее.Это навсегда изменит ваш взгляд на общее программирование.
Надеюсь, это поможет.