这是previous one的后续问题,这是我当前的示例:
test / package.scala
package object test {
sealed trait BaseTrait {
type T <: BaseState
def state: T
}
case class Foo(state: FooState) extends BaseTrait
case class Bar(state: BarState) extends BaseTrait
sealed trait BaseState
case class FooState(f: Integer = 1) extends BaseState
case class BarState(s: String = "abc") extends BaseState
}
test / base / BaseModel.scala
trait BaseModel[T <: BaseState] {
var baseVar: Option[T] = None
}
test / base / BaseProcessor.scala
trait BaseProcessor[T <: BaseTrait#T] {
def model: BaseModel[T]
def process(x: T): Unit = model.baseVar = Option(x)
}
test / foo / FooProcessor.scala
class FooProcessor(val model: FooModel) extends BaseProcessor[Foo#T] {
val v: Option[FooState] = model.baseVar
}
test / foo / FooModel.scala
class FooModel extends BaseModel[FooState]
test / bar / BarProcessor.scala
class BarProcessor(val model: BarModel) extends BaseProcessor[Bar#T] {
val v: Option[BarState] = model.baseVar
}
test / bar / BarModel.scala
class BarModel extends BaseModel[BarState]
test / Test.scala
object Test extends App {
val test = Test2
val foo = Foo(FooState())
val bar = Bar(BarState())
test.func(foo)
test.func(bar)
}
test / Test2.scala
class Test2 {
private implicit val fooProcessor = new FooProcessor(new FooModel)
private implicit val barProcessor = new BarProcessor(new BarModel)
def func[T <: BaseTrait](p: T) {
tfunc(p.state)
}
private def tfunc[T <: BaseTrait#T](p: T)(implicit processor: BaseProcessor[T]) {
processor.process(p)
}
}
我要实现的目标如下:
如果我尝试运行当前所拥有的内容,则会出现以下编译器错误:
我不太了解的找不到参数处理器的隐式值: base.BaseProcessor [p.T]
,因为tfunc都期望T <: BaseTrait#T
,而隐式处理器也具有相同的type参数,所以我希望编译器将它们匹配。
请注意,如果我将BaseTrait中的抽象类型更改为type T = BaseTrait
,则所有隐式函数似乎都与tfunc的预期类型匹配,因此我得到了
含糊的隐式值
编译器错误。在我看来,由于某种原因,编译器并没有真正正确地获得这些上限,但是我的假设可能是错误的。另外,如果我将tfunc更改为上下文绑定,并尝试通过implicitly[BaseProcessor[T]]
(或implicitly[BaseProcessor[p.T]]
,其中p为BaseTrait的上限)召唤适当的处理器,我将得到完全相同的结果。
我在这里错过了明显的东西吗,还是有另一种方法可以实现我在这里想要做的事情?