Scala 使用子类实现trait方法';类型
我想要一个traitScala 使用子类实现trait方法';类型,scala,inheritance,traits,Scala,Inheritance,Traits,我想要一个traitFoo来提供将函数应用于它的transform方法。另外,我想强制实现类使用increment方法,以某种方式转换对象。朴素的解决方案: trait Foo{ def转换(fun:Foo=>Foo):Foo=fun(this) def增量(n:Int):Foo } 案例类别A(A:Int)扩展了Foo{ //预期可用:转换(乐趣:A=>A):A //待实现:增量(n:Int):A ... } 上面说的行不通。。。继承的transform仍然期望Foo=>Foo,而不是A=>
Foo
来提供将函数应用于它的transform
方法。另外,我想强制实现类使用increment
方法,以某种方式转换对象。朴素的解决方案:
trait Foo{
def转换(fun:Foo=>Foo):Foo=fun(this)
def增量(n:Int):Foo
}
案例类别A(A:Int)扩展了Foo{
//预期可用:转换(乐趣:A=>A):A
//待实现:增量(n:Int):A
...
}
上面说的行不通。。。继承的transform
仍然期望Foo=>Foo
,而不是A=>A
,increment
仍然希望返回Foo
,而不是A
再尝试一次:
trait Foo{
def transform[C]:C=fun(这个.asInstanceOf[C])
def increment[C x.copy(x.a+1))//返回a(2)
我想知道是否有一个聪明的方法来完成它。获得所需的最直接的方法是将类型参数向上移动到trait声明。这就给出了
trait Foo[C]{…}
。但是,在转换中使用copy
仍然不起作用,因为Foo
特性不知道任何扩展它的东西。您可以通过以下方式提供更多信息:
A扩展了Foo[A]
在这里使用有点不方便,但它很有效,因为现在当你扩展Foo
时,它会将类型信息返回到trait。虽然这仍然有点不方便。事实证明,有一种技术我们可以在这里使用,来潜在地改进事情。首先,你设置你的trait。在一个type类中,有exactly每个类型对应一个trait实现,因此每个方法还应包含您要操作的实例:
trait Foo[C] {
def transform(c: C)(f: C => C): C
def increment(c: C, inc: Int): C
}
接下来,在伴生对象中,为您关心的类型设置typeclass的实例:
case class A(a: Int)
object Foo {
implicit val ATransform = new Foo[A] {
def transform (base: A)(f: A => A) = f(base)
def increment(base: A, inc: Int) = A(base.a+inc)
}
//Convenience function for finding the instance for a type.
//With this, Foo[A] is equivalent to implicitly[Foo[A]]
def apply[C](implicit foo: Foo[C]) = foo
}
现在我们可以按如下方式使用type类:
val b = A(3)
Foo[A].transform(b)(x=>x.copy(a=x.a+1)) //A(4)
Foo[A].increment(b,5) //A(8)
你确定你输入的是正确的吗?你能给出你所得到的具体错误吗?这对我来说似乎很好:这可能对你有帮助。TR;DR;我会使用一个类型的字符,也许是一个密封的特征。@ Ethan,这是行不通的。需要。
val b = A(3)
Foo[A].transform(b)(x=>x.copy(a=x.a+1)) //A(4)
Foo[A].increment(b,5) //A(8)