Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eliminate duplicate code whose only difference is the type

Tags:

scala

I have two structurally-equivalent class pairs whose only difference is the types. I would like to be able to merge V1 with V2 and K1 with K2. I control those four classes, but I am not able to modify takesDoublesOrLists - it comes from a library.

class V1 (
    val a: Double,
    val b: Double,
    // ...
    val z: Double
)

class K1(v: V1) {
    def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

class V2 (
    val a: List[Double],
    val b: List[Double],
    // ...
    val z: List[Double]
)

class K2(v: V2) {
    def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

I tried following the type class pattern, but got an error that the overloaded method takesDoublesOrLists could not be applied to my type parameter.

Edit:

The signature of the overloaded function takesDoublesOrLists is as the name suggests:

def takesDoublesOrLists(a: Double, b: Double, /* ..., */ z: Double): Something = /* ... */
def takesDoublesOrLists(a: List[Double], b: List[Double], /* ..., */ z: List[Double]): Something = /* ... */
like image 993
Nate Avatar asked Apr 17 '26 23:04

Nate


1 Answers

I can see how you could merge V1 and V2, but not K1 or K2:

class V[T] (
  val a: T,
  val b: T
  // ...
  val z: T
)

class K1(v: V[Double]) {
  def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

class K2(v: V[List[Double]]) {
  def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

EDIT: If your K1 and K2 classes are more complex than what you exemplified, you could break this behavior with traits:

trait KDoubles {
  def v: V[Double]
  def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

trait KLists {
  def v: V[List[Double]]
  def doIt = takesDoublesOrLists(v.a, v.b, /* ..., */ v.z)
}

class K {
  // common stuff ...
}

class K1 extends K with KDoubles {
  // ...
}

class K2 extends K with KLists {
  // ...
}
like image 78
ericbn Avatar answered Apr 20 '26 16:04

ericbn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!