Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't type parameters allowed in Scala auxiliary constructors?

Say I'm defining a simple 2D point class in Scala, and I want to be able to construct it with various types:

class Point(x:Float, y:Float) {
    this(x:Double, y:Double) = this(x.toFloat, y.toFloat)
    this(x:Int, y:Int) = this(x.toFloat, y.toFloat)
    // etc...
}

I want to boil this down using a template, such as:

class Point(x:Float, y:Float) {
    this[T](x:T, y:T) = this(x.toFloat, y.toFloat)
}

I know this won't work anyway, since T could be a type for which toFloat isn't defined, but the compiler error I get is:

no type parameters allowed here

Is this just unsupported in Scala? If so, why, and is there any simple way to get around this?

like image 862
maackle Avatar asked Sep 06 '11 22:09

maackle


People also ask

What is the purpose of auxiliary constructor in Scala?

The auxiliary constructor in Scala is used for constructor overloading and defined as a method using this name. The auxiliary constructor must call either previously defined auxiliary constructor or primary constructor in the first line of its body.

How do we define an auxiliary constructor?

Auxiliary constructors are defined by creating methods named this . Each auxiliary constructor must begin with a call to a previously defined constructor. Each constructor must have a different signature. One constructor calls another constructor with the name this .

Can Scala object have constructor?

There are two types of constructor in Scala – Primary and Auxiliary.

What is primary constructor in Scala?

The primary constructor of a Scala class is a combination of: The constructor parameters. Methods that are called in the body of the class. Statements and expressions that are executed in the body of the class.

How many auxiliary constructors can be created in a Scala class?

We are allowed to create any number of auxiliary constructors in our Scala class, but a scala class contains only one primary constructor. Auxiliary constructors are defined as methods in the class with the keyword this. We can describe multiple auxiliary constructors, but they must have different parameter lists.

What are the parameters of primary constructor in Scala?

The primary constructor may contain zero or more parameters. If we do not create a constructor in our Scala program, then the compiler will automatically create a primary constructor when we create an object of your class, this constructor is known as a default primary constructor. It does not contain any parameters.

What happens if apply method does not get defined in Scala?

If an apply method does not get define in the class and call this more than one time in the auxiliary constructor, then it will give a compile time error: In Scala, we can also create a primary constructor with a default value. If you don’t provide value, then it will take the default value, which is provided in the primary constructor.

Why constructor is not defined in Scala?

As we can see that there is no constructor defined in the class. In cases when the constructor is not defined explicitly Scala adds a default constructor with no arguments implicitly. So here, there is no need to define a constructor and perform operations inside it.


1 Answers

Scala's class constructors (unlike Java's) can't take type parameters, only the class itself can. As to why Scala made this design choice, I assume the main reason is simplicity.

If you want a secondary "builder" method that is generic, the natural thing to do is define it on the companion object. For example,

object Point {
  def build[T : Numeric](x: T, y: T) = {
    val n = implicitly[Numeric[T]]
    new Point(n.toFloat(x), n.toFloat(y))
  }
}

class Point(val x:Float, val y:Float)

val p = Point.build(1, 2) // Companion object's builder
p.x + p.y

Here I've used the Numeric typeclass to get a generic toFloat method.

like image 137
Kipton Barros Avatar answered Nov 20 '22 02:11

Kipton Barros