scalatypeclasstype-constraintsduck-typingstructural-typing

Defining generic type based on method (structural typing)


I am trying to declare a class with type based on some functions.

class A{
  def getC = 10
}

class B {
  def getC = 100
  def getB = 9
}


def readC[T <: {def getC():Int}](obj:T) = {
  obj.getC()
}

val a = new A()
val b  = new B()

readC(a)
readC(b) 

I expect that the readC should work with both A and B. also I can't make changes to A and B class so no trait-based solution will work here.

Also, Is there a better way to do it?


Solution

  • The problem is that

    def getC = 100
    

    is not the same function signature as

    def getC() = 100
    

    A and B have getC without () so you need to remove the () from the type constraint:

    def readC[T <: {def getC: Int}](obj: T) = {
      obj.getC
    }
    

    The better way to do this is to use a typeclass. Check online for a number of good tutorials on how to do this.