scalapolymorphismtype-bounds

Upper Type bound Polymorphic method Scala


I'm trying out some generic functions in Scala but I seem to be stuck trying to get the following example to work:

I've got the following (simplified) problem. I've got a parent config (which is a trait) and two case classes that inherit from this parent config. They both add one extra argument. Then I further got another Parent trait and 2 subclasses that extend this trait. These subclasses both implement the parents methods, it should have both a get config and a print config function. In my main class I then run a runner function which should first get the config, and subsequently print the config.

What I've tried is: changing the bounds, both in the parent and the children. I've also tried to change the return types. However this does not seem to work.


trait ParentConfig{val input : String}

case class ConfigOne(input:String, extraArg:String) extends ParentConfig

case class ConfigTwo(input:String, extraTwo:String) extends ParentConfig

trait inheritanceTester {

  def getConfig[A >: ParentConfig](): A

  def printConfig[A <: ParentConfig](conf: A): Unit
}


class ExtensionOne extends inheritanceTester {
 def getConfig[A >: ConfigOne](): A = {
   ConfigOne("test1","testOne")
 }

  def printConfig[A <: ConfigOne](conf:A): Unit  = {
    println(conf.extraArg)
  }
}

class ExtensionTwo extends inheritanceTester {
  def getConfig[A >: ConfigTwo](): A = {
    ConfigTwo("test2","testTwo")
  }

  override def printConfig[A <: ConfigTwo](conf:A): Unit  = {
    println(conf.extraTwo)
  }
}
object Main extends App {

  def run[A <: inheritanceTester](input: A): Unit = {
    val conf = input.getConfig()
    input.printConfig(conf)
  }

  val extensionOne = new ExtensionOne()
  run(extensionOne)

  val extensionTwo = new ExtensionTwo()
  run(extensionTwo)
}


at this point I'm getting the following error message when compiling:

Error:(26, 7) overriding method printConfig in trait inheritanceTester of type [A <: collections.ParentConfig](conf: A)Unit; method printConfig has incompatible type

Error:(36, 16) overriding method printConfig in trait inheritanceTester of type [A <: collections.ParentConfig](conf: A)Unit; method printConfig has incompatible type

It may be just be a silly question with an easy fix. But I'm kinda stuck. Could anyone perhaps point me in the correct direction on where to look? Am I perhaps using these bounds wrong or is this not a direct usecase for a polymorhic function?


Solution

  • Something like this?

    trait ParentConfig{val input : String}
    
    case class ConfigOne(input:String, extraArg:String) extends ParentConfig
    
    case class ConfigTwo(input:String, extraTwo:String) extends ParentConfig
    trait InheritanceTester[A <: ParentConfig] {
    
      def getConfig(): A
    
      def printConfig(conf: A): Unit
    }
    
    
    class ExtensionOne extends InheritanceTester[ConfigOne] {
      override def getConfig(): ConfigOne = {
       ConfigOne("test1","testOne")
      }
    
      override def printConfig(conf: ConfigOne): Unit  = {
        println(conf.extraArg)
      }
    }
    
    class ExtensionTwo extends InheritanceTester[ConfigTwo] {
      override def getConfig(): ConfigTwo = {
        ConfigTwo("test2","testTwo")
      }
    
      override def printConfig(conf: ConfigTwo): Unit  = {
        println(conf.extraTwo)
      }
    }
    object Main extends App {
    
      def run[A <: ParentConfig](input: InheritanceTester[A]): Unit = {
        val conf = input.getConfig()
        input.printConfig(conf)
      }
    
      val extensionOne = new ExtensionOne()
      run(extensionOne)
    
      val extensionTwo = new ExtensionTwo()
      run(extensionTwo)
    }