Scala предотвращают смешивание методов
Я хотел бы создать следующую черту:
trait IntSet[A] extends Traversable[A] { self: Product =>
def foreach[U](f: A => U): Unit
}
case class AProduct(a: List[Int], b: List[Int]) extends IntSet[Int] {
def foreach[U](f: Int => U): Unit = {
for(aa <- a; bb <- b) f(aa*bb)
}
}
AProduct(List(1, 5,6,7), List(2,3,4,5)).toString
возвращается
(2, 3, 4, 5, 10, 15, 20, 25, 12, 18, 24, 30, 14, 21, 28, 35)
Но я не хочу, чтобы метод toString из класса case был переопределен одним из проходимых! Как мне это преодолеть?
Я хочу, чтобы конечный результат был:
"AProduct(List(1, 5,6,7), List(2,3,4,5))"
и, если возможно, я хотел бы сделать что-то еще, чем следующее в IntSet:
override def toString = this.getClass().getName()+"("+self.productIterator.mkString(",")+")"
который работает, но я действительно хотел бы не изобретать велосипед.
1 ответ
Решение
Вам не нужно реализовывать IntSet
в AProduct
, Вы можете просто добавить все методы без наследования следующим образом:
case class AProduct(a: List[Int], b: List[Int])
object AProduct {
implicit class AProductIntSet(p: AProduct) extends Traversable[Int] {
def foreach[U](f: Int => U): Unit = {
for(aa <- p.a; bb <- p.b) f(aa*bb)
}
}
}
val ap = AProduct(List(1, 5,6,7), List(2,3,4,5))
// AProduct = AProduct(List(1, 5, 6, 7),List(2, 3, 4, 5))
ap.toString
// String = AProduct(List(1, 5, 6, 7),List(2, 3, 4, 5))
ap.map{_ + 1}
// Traversable[Int] = List(3, 4, 5, 6, 11, 16, 21, 26, 13, 19, 25, 31, 15, 22, 29, 36)
for{i <- AProduct(List(2), List(3, 5))} println(i)
// 6
// 10