0

I am very new to Scala so please don't vote me. What does expression this: Visitor[Double] ⇒ means? to me it looks like incomplete code. I tried to find this concept on Google but since I don't know this concept name I am unable to find it.

import scala.language.higherKinds

trait Expressions {

  trait TVisitor[T] {
    def visitConstant(v: Double): T
  }
  type Visitor[T] <: TVisitor[T]

  trait Expression {
    def accept[T](visitor: Visitor[T]): T
  }

  class Constant(val v: Double) extends Expression {
    def accept[T](visitor: Visitor[T]): T = visitor.visitConstant(v)
  }

  trait EvalVisitor extends TVisitor[Double] {
    def visitConstant(v: Double): Double = v
  }
}

trait AddExpressions extends Expressions {
  class Add(val l: Expression, val r: Expression) extends Expression {
    def accept[T](visitor: Visitor[T]): T = visitor.visitAdd(l, r)
  }

  trait TVisitor[T] extends super.TVisitor[T] {
    def visitAdd(l: Expression, r: Expression): T
  }
  type Visitor[T] <: TVisitor[T]

  trait EvalVisitor extends super.EvalVisitor with TVisitor[Double] {
    this: Visitor[Double] ⇒
    def visitAdd(l: Expression, r: Expression): Double =
      l.accept(this) + r.accept(this)
  }
}

trait ExtendedExpressions extends AddExpressions with MultExpressions {
  type Visitor[T] = TVisitor[T]
  trait TVisitor[T]
      extends super[AddExpressions].TVisitor[T]
      with super[MultExpressions].TVisitor[T]
  object EvalVisitor
      extends super[AddExpressions].EvalVisitor
      with super[MultExpressions].EvalVisitor
      with TVisitor[Double] {
    this: Visitor[Double] ⇒
  }
}

trait PrefixNotationForExpressions extends ExtendedExpressions {
  object PrefixNotationVisitor extends super.TVisitor[String] {
    this: Visitor[String] ⇒
    def visitConstant(v: Double): String = v.toString + " "
    def visitAdd(l: Expression, r: Expression): String =
      "+ " + l.accept(this) + r.accept(this)
    def visitMult(l: Expression, r: Expression): String =
      "* " + l.accept(this) + r.accept(this)
  }
}
Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
AZ_
  • 21,688
  • 25
  • 143
  • 191

1 Answers1

3

this: Visitor[Double] ⇒ is called a Self Type in Scala. The documentation for it can be read here.

In this example, it means that any class that implements PrefixNotiationForExpressions must also implement Visitor[String].

There is no equivalent to Self Types in Java. The most common question about them is why not declare the type within the extends clause of the trait. The following StackOverflow reference does a very good job at explaining this: What is the difference between self-types and trait subclasses?. The core difference boils down to whether we are representing a 'is a' relationship or a 'requires' relationship.

Chris K
  • 11,622
  • 1
  • 36
  • 49