0

Given an array of items I need to generate a sorted collection in Scala for a java.lang.reflect.Type but I'm unable to do so. The following snippet might explain better.

  def buildList(paramType: Type): SortedSet[_] = {
    val collection = new Array[Any](5)
    for (i <- 0 until 5) {
      collection(i) = new EasyRandom().nextObject(paramType.asInstanceOf[Class[Any]])
    }
    SortedSet(collection:_*)
  }

I'm unable to do as I get the error "No implicits found for parameter ord: Ordering[Any]". I'm able to work around this if I swap to an unsorted type such as Set.

  def buildList(paramType: Type): Set[_] = {
    val collection = new Array[Any](5)
    for (i <- 0 until 5) {
      collection(i) = new EasyRandom().nextObject(paramType.asInstanceOf[Class[Any]])
    }
    Set(collection:_*)
  }

How can I dynamically build a sorted set at runtime? I've been looking into how Jackson tries to achieve the same but I couldn't quite follow how to get T here: https://github.com/FasterXML/jackson-module-scala/blob/0e926622ea4e8cef16dd757fa85400a0b9dcd1d3/src/main/scala/com/fasterxml/jackson/module/scala/introspect/OrderingLocator.scala#L21

(Please excuse me if my question is unclear.)

Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
  • 4
    May I ask what is the meta-problem you are trying to solve? The joke of having one of the strongest type systems is to be able to solve and ensure the correctness of most problems at compile time. Having to use reflection and wonder how to do things at runtime usually _(not always, as there are always exceptions)_ means a problem in the design or trying to use **Scala** as **Python**, **JS** or any other dynamic language. – Luis Miguel Mejía Suárez May 19 '21 at 18:14

1 Answers1

1

This happens because SortedSet needs a contextual (implicit) Ordering type class instance for a given type A

However, as Luis said on the comment section, I'd strongly advice you against using this approach and using a safer, strongly typed one, instead.

Generating random case classes (which I suppose you're using since you're using Scala) should be easy with the help of some libraries like magnolia. That would turn your code into something like this:

def randomList[A : Ordering : Arbitrary]: SortedSet[A] = {
  val arb: Arbitrary[A] = implicitly[Arbitrary[A]]
  val sampleData = (1 to 5).map(arb.arbitrary.sample)

  SortedSet(sampleData)
}

This approach involves some heavy concepts like implicits and type classes, but is way safer.

Rodrigo Vedovato
  • 1,008
  • 6
  • 11