providence
providence

Reputation: 29463

Return types for unimplemented methods in traits

Suppose I have a trait SomeTrait with an unimplemented method func. This method is going to return something that extends SomeTrait. In other words, I've got something like the following:

trait SomeTrait
{
  def func(x: Int): SomeTrait
}

Now, I implement a class ExtensionClass that extends SomeTrait and it turns out that I in fact want the implementation of func in this class to return an object of type ExtensionClass:

class ExtensionClass(val param: String) extends SomeTrait
{
  override def func(x: Int): SomeTrait = return new ExtensionClass("test")

  // ExtensionClass also defines another method not specified in SomeTrait
  def anotherMethod: String = return param ++ "!"
}

So far, everything above works nicely. The problem arises if I want to call anotherMethod on the object returned by func like so:

val extension = new ExtensionClass("hello")
extension.func(5).anotherMethod

The type system only recognises that the object given by extension.func(5) is of type SomeTrait and so anotherMethod is not visible. This brings us to my question:

Question: Is it possible to make the above work without having to explicitly cast/pattern match on the result of func? For instance, can I update the type signature of func in SomeTrait so that some sort of type inference can happen? Any help will be appreciated.

Upvotes: 2

Views: 1108

Answers (1)

Lee
Lee

Reputation: 144126

You can add a generic parameter:

trait SomeTrait[T <: SomeTrait[T]] {
    def func(x: Int): T
}

class ExtensionClass(val param: String) extends SomeTrait[ExtensionClass] {
    def func(x: Int) = new ExtensionClass("test")
    def anotherMethod: String = param ++ "!"
}

alternatively you could add an abstract type member:

trait SomeTrait {
    type T <: SomeTrait
    def func(x: Int): T
}

class ExtensionClass(val s: String) extends SomeTrait {
    type T = ExtensionClass
    def func(x: Int) = new ExtensionClass("test")
    def anotherMethod: String = s ++ "!"
}

Upvotes: 6

Related Questions