Type Parameter is Scala

Class in Scala can receive a special parameter type, called Type Parameter.
This type of parameter is not the same as normal variables as other parameters, but a parameter that specifies the type. That’s why it’s called Type Parameter. While Class is defined, it is entirely possible to manipulate an unknown type (specified when calling a class), and that type is “conventionally” type parameterized.

class Super[T,R](name: T, age: R) {

def kamehameha(power: R) = {

println(name.toString() + age.toString() + ‘:’ + power.toString())

} }

val supper = new Super[String,Int](“Goku”,100)

supper.kamehameha(1000) // Goku100:1000

supper.kamehameha(“kameeee”) // type mismatch

Here T and R are Type Parameters. T and R are used to specify the type of the parameter of the class (name, age) and type for the parameter of the function (power). When creating goku variables, we need to specify T and R styles with square brackets (same as when defined).

At the time the goku variable was created, an instance of the SuperSaiyan class was formed, and in it the uniform R was String and T was unified to Int.

Pai

I will mention a practical application of Type Parameter. When writing methodically, sometimes we want the value returned to be not just a single value, but (for example) as a pair of values. There are usually two ways

To return a value in the return type, the remaining value passed as a parameter and in the method will change it
Creates a new data type that holds all values, and returns just that type of data.
Any way to do is also problematic. If you have experience, you will see the following shortcomings

Method 1 is a very “matriarchal” approach, changing the value of input and output parameters, in contrast to best-practice in programming. The latter will be “trapped” when not aware of the change of parameters
Method 2 can be used well in cases where the new data type is a meaningful data type. If your goal is simply to pack two values ​​and force a data type to make no sense, the code will be difficult to read and not clear.
The recommended way is to create a Pair data type.

Class Pair [T1, T2] (val t1: T1, val t2: T2) {
Override def toString (): String = “(” + t1 + “,” + t2 + “)”
}
Pair T1 and T2 are 2 Type Parameters, meaning that two values ​​can be of different types as you like. Now we can use the Pair style to “catch” the return value of a method, here is the teamUp method

Saiyan class (name: String, power: Int) {
Def change (): Saiyan = new Saiyan (name, power * 100)
Override def toString (): String = name + ‘/’ + power.toString
}
Class Namek (name: String, power: Int) {
Def change (): Namek = new Namek (name, power * 10)
Override def toString (): String = name + ‘/’ + power.toString
}

Def teamUp (left: Saiyan, right: Namek): Pair [Saiyan, Namek] = new Pair [Saiyan, Namek] (left.change (), right.change ()

Val goku = new Saiyan (“Kakarot”, 200) // Saiyan = Kakarot / 200
Val picolo = new Namek (“Gabriel”, 70) // Namek = Gabriel / 70
TeamUp (goku, picolo) // Pair [Saiyan, Namek] = (Kakarot / 20000, Gabriel / 700)
Here the return type of teamUp is Pair [Saiyan, Namek]. We have just implemented the Tuple data type.

Tuple is a good choice to use, so Scala has prepared 22 Tuples available from Tuple1 to Tuple22. These 22 Tuples allow up to 22 values ​​in the same group. Creating an instance for Tuple is very simple

New Tuple2 (goku, picolo)
Or maybe even shorter

(Goku, picolo)
Variance

Regarding Type Parameter, I will write about Covariant and Invariant. Must recognize the Vietnamese words difficult to remember and difficult to understand, so I will use the English term in this article.

Invariant

What is Invariant?
When we have a class C, two type parameters T1 and T2, only when T1 = T2 is the following assignment expression accepted:

Val: G [T1] = G [T2]
The way of thinking of Invariant is very natural and consistent with normal logic. When two types are different, there is no possibility that a class of two types can be assigned to each other!

Array in Java is a class that should have been Invariant, but was designed to be Covariant. This is a weakness in Java’s language design.

When Java was first created (historical reason: smile :), the concept Generic (a.k.a parametric polymorphism) was not popular, so the creator of Java had to make the array Covariant.

Wait, did not say how is Covariant?
Covariant

When we have a class C, two type parameters T1 and T2, only if T2 inherits T1 will the following assignment be accepted:

Val: G [T1] = G [T2]
In Scala, when assigning a Type Parameter, the default is Invariant. If you want to specify Covariant then you need to write:

Class G [+ T]
The theory of Invariant and Covariant is somewhat abstract and confusing. I will take the example below. Language is Java. You look at G as array, T1 as String, T2 as Object.

Object [] objects = new String [1];
Objects [0] = 100;
What’s the code above?
Take note, we are taking a String array assigned to an Object array. The above code can compile normally but when run will throw Exception java.lang.ArrayStoreException. The reason is that line 2 has thrown an int value into the String array.

The same logic as above, Scala will catch errors when compile in the first line

Scala> val arr: Array [Any] = new Array [String] (1)
<Console>: 7: error: type mismatch;
Found: Array [String]
Required: Array [Any]
This difference comes from the design. Array in Scala is Invariant while Array in Java is Covariant as mentioned above. In this respect, Scala is considered Type Safe over Java, as it can catch errors from compile.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s