这是一个简单的例子:
trait RRBound {
type RR[T]
def apply[T]: T => RR[T]
}
trait Z2 extends RRBound {
type RR[T] = T match {
case Option[i] => Seq[i]
}
override def apply[T]: T => RR[T] = T match {
case Option[i] => (v: Option[i]) => v.toSeq
// invalid syntax here
}
}
trait AlsoZ2 {
def apply[i]: Option[i] => Seq[i] = {v => v.toSeq}
}
显然
T match
只能在类型定义中使用,因此实现apply[T]: T => RR[T]
的唯一方法是在多个子类型中执行它,这也意味着Z2无法轻松转换为AlsoZ2,尽管它们在功能上是相同的。
这里可以做什么来完成Z2并使AlsoZ2变得不必要?
你能让
apply
内联吗?
trait RRBound {
type RR[T]
inline def apply[T]: T => RR[T]
}
尝试
override inline def apply[T]: T => RR[T] = (v: T) => summonFrom {
case given (T =:= Option[i]) => summonFrom {
case given (Seq[`i`] =:= RR[T]) =>
(v: Option[`i`]).toSeq
}
}
或
override inline def apply[T]: T => RR[T] = (v: T) => erasedValue[T] match {
case _: Option[i] => summonFrom {
case given (T =:= Option[`i`]) => (v: Option[`i`]).toSeq
}
}