Concatenating several values where the type has a Show instance

Viewed 66

I want to write a function showAll that takes a List of values and produces a String obtained by concatenating the String representations of each of the values, using the Show instances available in implicit scope.

There should be no constraint on the type of the elements of the list, other than the presence of the Show instance.

For example:

case class Person(name: String)
implicit val showPerson: Show[Person] = Show.by(_.name)
showAll(List(1, Person("Martin")))

should output:

1 Martin

In this case the function is using Show[Int] and Show[Person] instances.

What would be a proper signature for the function?

Thanks.

1 Answers

Here is my sample code , which probably solve your problem. I have created generic method show all as you require to show elements of List. also an implicit method for specific field values. MyClass trail is identifier. if Myclass won't extended by any case class specific field wont be printed.

trait Myclass
  case class Person(name: String) extends Myclass
  case class Admin(name: String,age:Long) extends Myclass

  def main(args: Array[String]): Unit = {
    showAll[Myclass](List(1, 2, Person("Martin"),Admin("Bob",30)))
  }

  implicit def showField: String = "name"

  def showAll[T <: Myclass : ClassTag](listOfValues: List[Any]): Unit = {
    listOfValues.foreach { data =>
      if (data.isInstanceOf[T]) {
        val myInstance= data.asInstanceOf[T]
        val fld = myInstance.getClass.getDeclaredField(showField)
        fld.setAccessible(true)
        val value = fld.get(myInstance).asInstanceOf[String]
        print(value + " ")
      }
      else
        print(data + " ")
    }
  }
Related