views:

141

answers:

3

I'm obviously missing something about why the following does not compile:

trait SomeTrait{
def homepageClass[A <: SomeType]: Class[A]
}

class SomeOtherType extends SomeType

object SomeObject extends SomeTrait{
def homepageClass = classOf[SomeOtherType]
}
+11  A: 

The problem here is that the following two declarations are different:

def homepageClass[A <: SomeType]: Class[A]  // has type parameters
def homepageClass = classOf[SomeOtherType]  // doesn't have type parameters

To accomplish what you want you need to declare an abstract type, like this:

trait SomeTrait{
  type A <: SomeType
  def homepageClass: Class[A]
}

object SomeObject extends SomeTrait {
  type A = SomeOtherType
  def homepageClass: Class[A] = classOf[SomeOtherType]
}

Or

trait SomeTrait[A <: SomeType] {
  def homepageClass: Class[A]
}


object SomeObject extends SomeTrait[SomeOtherType] {
  def homepageClass: Class[SomeOtherType] = classOf[SomeOtherType]
}
Daniel
+2  A: 
def homepageClass[A <: SomeType]: Class[A]

says "whatever subclass A of SomeType you give, I can return a Class[A]. In particular, it can be called like this:

class SomeThirdType extends SomeType

val x: Class[SomeThirdType] = SomeObject.homepageClass[SomeThirdType]

A more direct equivalent than Daniel gives is an existential type:

trait SomeTrait{
  def homepageClass: Class[A forSome {type A <: SomeType}] 
}

or

trait SomeTrait{
  def homepageClass: Class[_ <: SomeType] 
}

UPDATE: Two differences between solutions I can think about:

  1. Existential types produce the same bytecode as Java wildcards (and their major intended use is interoperation with wildcards).

  2. You can write a refinement type for the abstract type member solution:

     val x: SomeTrait {type A = SomeOtherType} = SomeObject
    

    I don't think you can for existential types.

Any others?

Alexey Romanov
If you now explain the difference between my suggestion and the existential type version, that would be great! :-)
Daniel
A: 

Thank you Daniel and Alex, I didn't expect answers so soon.

@muphta: You should accept one of them!
Randall Schulz