Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 使用子类实现trait方法';类型_Scala_Inheritance_Traits - Fatal编程技术网

Scala 使用子类实现trait方法';类型

Scala 使用子类实现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=>

我想要一个trait
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)