Scala type polymorphism from parameter to return type, within type hierarchy -


i have collection of type collection[supertype]. stored in collection several values subtypes of supertype, collection allow contain 1 instance of each subtype (a bit set, not).

i trying write function when given companion object of 1 of above mentioned subtypes, can return first instance of class companion object belongs to.

initially tried set shown below, t suffer type erasure, pattern matching fail. realised set wasn't suitable task, because want 1 occurrence of each subtype in collection.

def get[t <: supertype](target: t): option[supertype] =   collection.collectfirst({     case target: t => target   }) 

my next, , current approach using map, key companion object , value instance of companion object's class. type hierarchy show below.

trait supertype trait supertypevalue  // pretend has parameters case class examplesubtype extends supertypevalue  case object examplesubtype extends supertype {   // value use in later example   val uniquetoobjectfield: string = "hello" }  val collection: map[supertype, supertypevalue] = // new map  def get(target: supertype): option[supertypevalue] =   collection.get(target) 

the above works enough. however, preserve type of subtype used parameter, , use return type. believe signature of function this:

get[t <: supertype](target: t): option[t]  // get(examplesubtype) match {   case some(examplesubtype) => examplesubtype.uniquetoobjectfield   case _ => "nope" } 

is possible within scala? if so, how? if not, exist in other languages , called?

hopefully there no glaring issues question, it's 2am shall check things on again in morning.

you can use classtags around type erasure. instead of using companion object, might easier provide generic parameter explicitly:

import scala.reflect._  trait supertype { val x: int }  case class foo(x: int) extends supertype case class bar(x: int) extends supertype  val collection = set(foo(1), foo(2), bar(3), foo(4), bar(5)) def get[t <: supertype : classtag]: option[t] = {     collection.collectfirst {         case target: t => target     } } 

and can call:

get[foo] //foo(1) get[bar] //bar(3) 

Comments