I have a trait
trait A {
def doSomething(a: Seq[Int]): Seq[String] = {
a.map {
case AA(s) => s // want to use unapply defined in trait (this(AA) not allowed)
case _ => "idc"
}
}
def unapply(a: Int): Option[String] = getString(a)
def getString(a: Int): Option[String] = {
a match {
case 1 => Some("one")
case 2 => Some("two")
case _ => None
}
}
}
object AA extends A
object AA2 extends A {
override def getString(a: Int): Option[String] = {
super.getString(a).orElse{
a match {
case 3 => Some("three")
case 4 => Some("four")
case _ => None
}
}
}
}
object MyClass {
def main(args: Array[String]) {
println(AA.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, idc, idc, idc)
println(AA2.doSomething(Seq(1,2,3,4,5))); // Expect Output: List(one, two, three, four, idc) but get List(one, two, idc, idc, idc)
}
}
The problem here is I can't use the unapply defined in the trait without creating an extractor object.
I would like to override the getString method in different objects using this trait.
CodePudding user response:
You can use a self type to reference yourself.
trait A { self =>
final def doSomething(a: Seq[Int]): Seq[String] =
a.map {
case self(s) => s
case _ => "idc"
}
final def unapply(a: Int): Option[String] =
getString(a)
def getString(a: Int): Option[String] =
a match {
case 1 => Some("one")
case 2 => Some("two")
case _ => None
}
}
Which works as expected.
Code running here.
CodePudding user response:
One solution I used was
trait A {
def doSomething(a: Seq[Int]): Seq[String] = {
a.map {
case Extractor(s) => s
case _ => "idc"
}
}
object Extractor {
def unapply(a: Int): Option[String] = getString(a)
}
def getString(a: Int): Option[String] = {
a match {
case 1 => Some("one")
case 2 => Some("two")
case _ => None
}
}
}
object AA extends A
object AA2 extends A {
override def getString(a: Int): Option[String] = {
super.getString(a).orElse{
a match {
case 3 => Some("three")
case 4 => Some("four")
case _ => None
}
}
}
}
object MyClass {
def main(args: Array[String]) {
println(AA.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, idc, idc, idc)
println(AA2.doSomething(Seq(1,2,3,4,5))); // Output: List(one, two, three, four, idc)
}
}