我希望有一个trait Foo
,提供了一个transform
方法,可以对它应用函数。此外,我想强制要求实现该trait的类都拥有一个increment
方法,该方法也能以某种方式转换对象。天真的解决方案:
trait Foo {
def transform(fun: Foo => Foo): Foo = fun(this)
def increment(n: Int): Foo
}
case class A(a: Int) extends Foo {
// expecting available: transform(fun: A => A): A
// to be implemented: increment(n: Int): A
...
}
上述方法行不通...继承的
transform
仍然期望 Foo => Foo
,而不是 A => A
,并且 increment
仍然需要返回 Foo
,而不是 A
。再试一次:
trait Foo {
def transform[C <: Foo](fun: C => C): C = fun(this.asInstanceOf[C])
def increment[C <: Foo](n: Int): C
}
case class A(a: Int) extends Foo {
def increment(n: Int) = A(a + n)
}
A
无法编译——它仍然会报告有关签名的问题。
去掉increment
函数后,transform
可以工作。但是,asInstanceOf
看起来有点不安全。此外,我需要显式提供类型参数给transform
:
val a = A(1)
a.transform[A](x => x.copy(x.a + 1)) // returns A(2)
我想知道是否有一种聪明的方法可以完成它。