views:

115

answers:

2

Hi,

I am trying to understand type members in Scala. I wrote a simple example that tries to explain my question.

First, I created two classes for types:

class BaseclassForTypes
class OwnType extends BaseclassForTypes

Then, I defined an abstract type member in trait and then defined the type member in a concerete class:

trait ScalaTypesTest {
  type T <: BaseclassForTypes

  def returnType: T
}

class ScalaTypesTestImpl extends ScalaTypesTest {
  type T = OwnType

  override def returnType: T = {
    new T
  }
} 

Then, I want to access the type member (yes, the type is not needed here, but this explains my question). Both examples work.

Solution 1. Declaring the type, but the problem here is that it does not use the type member and the type information is duplicated (caller and callee).

val typeTest = new ScalaTypesTestImpl
val typeObject:OwnType = typeTest.returnType // declare the type second time here
true must beTrue

Solution 2. Initializing the class and using the type through the object. I don't like this, since the class needs to be initialized

val typeTest = new ScalaTypesTestImpl
val typeObject:typeTest.T = typeTest.returnType // through an instance
true must beTrue

So, is there a better way of doing this or are type members meant to be used only with the internal implementation of a class?

+5  A: 

You can use ScalaTypesTestImpl#T instead of typeTest.T, or

val typeTest:ScalaTypesTest = new ScalaTypesTestImpl
val typeObject:ScalaTypesTest#T = typeTest.returnType
Yardena
Great! Thanks. Where did you find this information?
Pekka Mattila
Welcome. Frankly I don't remember where I first saw this (probably in some example on the web), but it's also in the spec - section 3.2.2 "Type Projection".
Yardena
+2  A: 

If you don't want to instance ScalaTypesTestImpl, then, perhaps, you'd be better off putting T on an object instead of class. For each instance x of ScalaTypesTestImpl, x.T is a different type. Or, in other words, if you have two instances x and y, then x.T is not the same type as y.T.

Daniel
Thanks for the tip! However, I cannot change the implementation where I really faced this problem, since it is third party library that I don't want to change.
Pekka Mattila