我想我有一个解决您问题的方法,请查看以下代码:
val f: Int => Boolean = _ => true
trait X[A] {
def m1: Unit
}
implicit def funcToX[A](f: A => Boolean): X[A] = new X[A] {
override def m1: Unit = println("Hello x")
}
f.m1 // Works
trait Y[A] {
def m2: Unit
}
implicit def toY[T[_,_], A](x: T[A, Boolean])(implicit toX: T[A, Boolean] => X[A]): Y[A] = new Y[A] {
override def m2: Unit = {
x.m1
println("Hello y")
}
}
f.m2 // now works
我在这里使用更高种类的类型语法。它是 scala 语言的高级功能,我没有足够的经验来正确解释它。转换 toY 应该适用于恰好采用两个类型参数的任何类型(并且已定义转换“toX”)。
问题是你真的需要转换 toY 才能在参数 T 上通用吗?也许它接受函数作为参数就足够了:
implicit def toY[A](x: A => Boolean)(implicit toX: (A => Boolean) => X[A]) = ???
您可以阅读更多关于更高种类的类型,例如这篇文章:
Scala:更高类型的类型
更新
根据问题作者的要求,我提出了以下解决方案:
type SingleGenericFun[T] = T => _
val f: SingleGenericFun[Int] = _ > 42
val g: Int = 42
trait X[A] {
def m1: Unit
}
implicit def toX(f: SingleGenericFun[Int]): X[Int] = ???
implicit def toX(x: Int): X[Int] = new X[Int] {
override def m1: Unit = println(x)
}
f.m1 // Works
trait Y[A] {
def m2: Unit
}
implicit def toY2[T[_, _], A](x: T[A, _])(implicit toX: T[A, Boolean] => X[A]): Y[A] = new Y[A] {
override def m2: Unit = {
x.m1
println("Hello y!")
}
}
implicit def toY0[A](x: A)(implicit toX: A => X[A]): Y[A] = new Y[A] {
override def m2: Unit = {
x.m1
println("Hello y!")
}
}
implicit def toY1[T[_], A](x: T[A])(implicit toX: T[A] => X[A]): Y[A] = new Y[A] {
override def m2: Unit = {
x.m1
println("Hello y")
}
}
g.m2
f.m2 // Compile
它仍然不是最好的解决方案,因为它需要提供 3 种(甚至更多)在技术上做同样事情的方法,我不知道如何泛化它,也不知道它是否可能。