Учитывая некоторые типы с более высоким родом:
trait Impl [S]
trait Event[S, A]
trait Key [A]
Как я могу переписать следующее определение:
def declare[A](fun: Impl[_] => Event[_, A]): Key[A] = ???
, чтобы аргумент fun
действительно был Impl[S] => Event[S, A]
для некоторых S
.Например, в следующем случае:
trait Impl[S] { def ev1: Event[S, Int]; def ev2: Event[T, Int] }
Это будет действительный вызов:
declare(_.ev1)
, но это не так:
declare(_.ev2) // this currently compiles
РЕДАКТИРОВАТЬ
Вот более полный пример, который точно показывает, почему я сталкиваюсь с проблемами:
trait Sys [S <: Sys[S]]
trait Event[S <: Sys[S], A, Repr]
trait Decl {
type Impl[S <: Sys[S]]
protected def declare[U](fun: Impl[_] => Event[_, U, Impl[_]]): Unit = ???
}
Следующее событие, объявляющее объект-компаньон, не компилируется:
object Test extends Decl {
type Impl[S <: Sys[S]] = Test[S]
case class Renamed(name: String)
declare[Renamed](_.renamed)
}
trait Test[S <: Sys[ S]] {
def renamed: Event[S, Test.Renamed, Test[S]]
}
из-за некоторой проблемы с сопоставлением типов:
error: type mismatch;
found : Event[_$1,Test.Renamed,Test[_$1]] where type _$1
required: Event[_, Test.Renamed, Test.Impl[_]]
Note: _$1 <: Any, but trait Event is invariant in type S.
You may wish to define S as +S instead. (SLS 4.5)
Note: Test[_$1] <: Test[_], but trait Event is invariant in type Repr.
You may wish to define Repr as +Repr instead. (SLS 4.5)
declare[ Renamed ]( _.renamed )
^
Если я изменю тип функции на Impl[_] => Event[_, U, _]
, она компилируется, но я действительно хотел бы восстановить некоторую безопасность типов.