Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Right arrow in class body in Scala

Tags:

scala

Looking through the Scala source code, I stumbled across Enumeration.scala:

abstract class Enumeration(initial: Int, names: String*) extends Serializable {
  thisenum =>

  def this() = this(0)
  def this(names: String*) = this(0, names: _*)    

  /* Note that `readResolve` cannot be private, since otherwise
     the JVM does not invoke it when deserializing subclasses. */
  protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get()

  // ... SNIP ...

}

What is the the thisenum => for? I couldn't find any info in the "Programming in Scala" book.

like image 889
Charles Avatar asked Feb 12 '11 20:02

Charles


People also ask

What does arrow mean in Scala?

Arrow is a type class for modeling composable relationships between two types. One example of such a composable relationship is function A => B ; other examples include cats. data. Kleisli (wrapping an A => F[B] , also known as ReaderT ), and cats.

What is the meaning of => in Scala?

=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .

Is everything in Scala an object?

Not everything is an object in Scala, though more things are objects in Scala than their analogues in Java. The advantage of objects is that they're bags of state which also have some behavior coupled with them. With the addition of polymorphism, objects give you ways of changing the implicit behavior and state.

When we are writing a Scala program we always start with object instead of using a class like Java What is that type of object is?

Instead, Scala has singleton objects. A singleton is a class that can have only one instance, i.e., Object. You create singleton using the keyword object instead of class keyword.


2 Answers

The Programming in Scala 2d edition introduce the concept of self type in the section 29.4 "Splitting modules into trait":

The SimpleFoods trait could look as:

trait SimpleFoods {
  object Pear extends Food("Pear")
  def allFoods = List(Apple, Pear)
  def allCategories = Nil
}

So far so good, but unfortunately, a problem arises if you try to define a SimpleRecipes trait like this:

trait SimpleRecipes { // Does not compile
  object FruitSalad extends Recipe(
    "fruit salad",
    List(Apple, Pear), // Uh oh
    "Mix it all together."
  )
  def allRecipes = List(FruitSalad)
}

The problem here is that Pear is located in a different trait from the one that uses it, so it is out of scope.
The compiler has no idea that SimpleRecipes is only ever mixed together with SimpleFoods.
There is a way you can tell this to the compiler, however. Scala provides the self type for precisely this situation.
Technically, a self type is an assumed type for this whenever this is mentioned within the class.
Pragmatically, a self type specifies the requirements on any concrete class the trait is mixed into.
If you have a trait that is only ever used when mixed in with another trait or traits, then you can specify that those other traits should be assumed.
In the present case, it is enough to specify a self type of SimpleFoods, as shown:

trait SimpleRecipes {
  this: SimpleFoods =>
  object FruitSalad extends Recipe(
    "fruit salad",
    List(Apple, Pear), // Now Pear is in scope
    "Mix it all together."
  )
  def allRecipes = List(FruitSalad)
}

Given the new self type, Pear is now available.
Implicitly, the reference to Pear is thought of as this.Pear.
This is safe, because any concrete class that mixes in SimpleRecipes must also be a subtype of SimpleFoods, which means that Pear will be a member.
Abstract subclasses and traits do not have to follow this restriction, but since they cannot be instantiated with new, there is no risk that the this.Pear reference will fail

like image 159
VonC Avatar answered Nov 15 '22 18:11

VonC


It's a self type. See section 29.4 of Programming in Scala Second Edition. I don't think it was covered on the first edition, and I don't have one around to lookup anyway.

All that did, in this example, was make sure thisenum would refer to Enumeration's this from any inner of Enumeration.

like image 28
Daniel C. Sobral Avatar answered Nov 15 '22 17:11

Daniel C. Sobral