0

I wonder how can I preserve my type constraints while trying to workaround over 'Covariant type parameter in a wrong position problem' situation. Here is the code:

trait Converter[SourceType, +JobType <: ConverterJobType[SourceType]] {
   def convert[JT >: JobType](job: JT):String = job.someMethodFromJobType()// method is not accessible here. I would like to use JobType but actually job is treated like type Any.
}

object Converter{
   implicit object CSVConverter extends Converter[CSV, CSVConverterJobType]{
     def converter....
   }
 }

I need covariance so that my implicit object could be looked up.

 case class CSVConverterJobType(...) extends ConverterJobType[SourceType]

 object Application {

    def process[T](job: List[T])(implicit 
       converter:Converter[T,ConverterJobType[T]]) = {...}

    val list:List[CSV] = ...
    process(list)

 }

In order to process method to be able to find implicit.... I need to make second type parameter covariant. But then I'm not able to use actual type information in convert method.

Any idea how to overcome this?

Deil
  • 492
  • 4
  • 14

1 Answers1

2

JT needs to be <: JobType in order for job.someMethodFromJobType() to work. If JT is an arbitrary supertype of JobType then it doesn't have a someMethodFromJobType() method.

You should convert the second type argument to a type member, especially if there is only one JobType per SourceType (if not, the implicit search won't work anyway as it won't know which JobType to choose):

trait Converter[SourceType] {
  type JobType <: ConverterJobType[SourceType]
  def convert...
}

object Converter{
  implicit object CSVConverter extends Converter[CSV]{
    type JobType = CSVConverterJobType
    def convert....
  }
}
Ziyang Liu
  • 810
  • 4
  • 10
  • 1
    Thank you for your reply @Ziyang Liu. I introduced JT type because in case of I'm using covariance for second type parameter I can't use this type for method's parameter anymore( function input parameter is contrvariant). Yes..you are right...it wouldn't be able to resolve such an ambiguity in case of multiple JobType per SourceType. I was trying to use type members... and maybe it is easier to use for my case because basically these types are paired...CSV goes with CSVConverterJobType and so on. But I was shifted tow more complicated solution. But your answer helps me clarify my case. Tnx! – Deil Sep 21 '17 at 20:59
  • Today I've tried to use type member for JobType and it's the same problem.... compiler treat it like covariant type and therefore I still can't use it in my method's parameter list. – Deil Sep 22 '17 at 10:15
  • I'm thinking of using Magnet pattern for this. Will let anyone know about results. But still open for suggestion how to make it works through type constraints. – Deil Sep 22 '17 at 10:19
  • You should be able to use type member in a parameter list. It will be helpful if you can update your question to include exactly what you tried to do. – Ziyang Liu Sep 22 '17 at 14:04
  • Actually it is in my question. I need to call method `someMethodFromJobType` on a job. For that I need to pass job into convert method. When we use type member `type JobType <: ConverterJobType[SourceType]` it implicitly makes JobType convariant( only in case when type constraint is a generic type). And that is why I can't pass it into method's parameter list. – Deil Sep 23 '17 at 17:56