user8162258
user8162258

Reputation:

Inheriting abstract types causing error saying that class is not an enclosing class

I am new to scala and am having trouble with inheriting from abstract type members. The code is the basis of a behaviour trees library I am building to get myself used to scala. I have simplified my code to something which best represents the problem:

trait Task {
  type DataIn
  type DataOut

  def run(item: DataIn): (Boolean,Option[DataOut])
}

trait TaskContainer extends Task {
  def task: Task
}

case class ResultInverter[I](override val task: Task{
    type DataIn = ResultInverter.this.DataIn}) 
  extends TaskContainer {
  type DataIn = I
  type DataOut = Nothing

  override def run(item: DataIn): (Boolean,Option[DataOut])={
    val taskOut = task(item)
    if (taskOut._1 == true) ((false,None))
    else (true,None)
  }
}

object TaskTest extends App {
  val isPositive = new Task {
    type DataIn = Int
    type DataOut = Nothing

    override def run(item: DataIn): (Boolean,Option[DataOut])={
      (item > 0, None)
    }
  }

  println(ResultInverter[Int](isPositive(1)._1))
}

this gives the errors

error: ResultInverter is not an enclosing class
      type DataIn = ResultInverter.this.DataIn}) 
                    ^
error: Task{type DataIn = } does not take parameters
      val taskOut = task(item)
                        ^
error: stable identifier required, but .this found.
      type DataIn = ResultInverter.this.DataIn}) 
                    ^
error: Task{type DataIn = Int; type DataOut = Nothing} does not take parameters
    val isNegative = ResultInverter[Int](isPositive(1)._1

I believe that error is coming from the line type DataIn = ResultInverter.this.DataIn. I have tried changing this to type DataIn = ResultInverter#DataIn but very little changed in terms of errors. I have programmed in java before so would have used type parameters instead of type members but I am pretty sure that type members are recommended.

Thanks for your help

Upvotes: 1

Views: 85

Answers (1)

Jasper-M
Jasper-M

Reputation: 15086

You can't reference this in the signature of a constructor. At the moment a constructor is invoked there is no this yet. In your case you can just use I instead.

case class ResultInverter[I](task: Task{ type DataIn = I }) extends TaskContainer { ... }

The other errors are because you attempt to call the apply method (a(b) translates to a.apply(b)), but Task only has a run method.

Upvotes: 1

Related Questions