Simon
Simon

Reputation: 6490

Scala: generic function with nested case classes

I would like to do a generic function able to sort different nested case classes by one of their "sub" argument in common.

For the moment I have done this:

 sealed trait SortableByGeoPoint {
    val geographicPoint: Int
  }
  case class A(id: Int, geographicPoint: Int) extends SortableByGeoPoint
  case class B(image: String, geographicPoint: Int) extends SortableByGeoPoint

  case class C(a: A, other: String)
  case class D(b: B, other: Int)

  def sortByGeoPoint(sequence: Seq[SortableByGeoPoint]): Seq[SortableByGeoPoint] = sequence.sortBy(_.geographicPoint)

It works well to sort a sequence of class A or class B, but I would like to make it work for a case class C or D (that contain a SortableByGeoPoint sub-class) How can I accomplish this?

I took a look at shapeless but didn't find a way to do this, but any way to do it (knowing that I will add later other classes like the class C or D), would be perfect.

Upvotes: 2

Views: 233

Answers (1)

pedrofurla
pedrofurla

Reputation: 12783

I think you are missing some form of type constraint. The most straight forward way to make your example code compile is by doing:

case class C(a: A, other: String) extends SortableByGeoPoint {
  val geographicPoint: Int = a.geographicPoint
}
case class D(b: B, other: Int) extends SortableByGeoPoint {
  val geographicPoint: Int = b.geographicPoint
}

This might or not meet your requirements. So, let's make yet another one:

case class Z[T](b: SortableByGeoPoint, other: T)
def sortByGeoPoint2(sequence: Seq[Z]): Seq[Z] = sequence.sortBy(_.b.geographicPoint)

In fact, I can think of many other ways to achieve this same outcome. Too many to enumerate. If you can illustrate a few other requirements I might be able to find a more suitable solution.

Upvotes: 4

Related Questions