Search code examples
scalatype-parameter

Is it possible to write a method in Scala returning objects with different type parameter?


Is it possible to write a method in Scala which returns an object of a type-parameterized class with different type paramter ? Something like this:

class A[T]

def f(switch: Boolean): A = if(switch) new A[Int] else new A[String]

Please note: The Code above is fictional to show the type of problem; The code above does not make semantically sense.

The code above will not compile because return type A is not parameterized.


Solution

  • You can, and you can even do it with type-safety with the aid of implicit arguments that encapsulate the pairings:

    class TypeMapping[+A,B] {
      def newListB = List.empty[B]
    }
    trait Logical
    object True extends Logical
    object False extends Logical
    
    implicit val mapFalseToInt = new TypeMapping[False.type,Int]
    implicit val mapTrueToString = new TypeMapping[True.type,String]
    
    def f[A <: Logical,B](switch: A)(implicit tmap: TypeMapping[A,B]) = tmap.newListB
    
    scala> f(True)
    res2: List[String] = List()
    
    scala> f(False)
    res3: List[Int] = List()
    

    You do have to explicitly map from boolean values to the custom True and False values.

    (I have chosen List as the target class just as an example; you could pick anything or even make it generic with a little more work.)

    (Edit: as oxbow_lakes points out, if you need all possible return values to be represented on the same code path, then this alone won't do it, because the superclass of List[Int] and List[String] is List[Any], which isn't much help. In that case, you should use an Either. My solution is for a single function that will be used only in the True or False contexts, and can maintain the type information there.)