As we already know that Dotty is the new Scala version and will obviously be more stronger and powerful then Scala 2.
In Scala-2, pattern matching is only applicable to the objects and not on the types. But with the new Scala compiler i.e Dotty, it is possible to apply matching on Types also.
For example,
type Container[C] = C match {
case String => Char
case Array[Int] => Int
case Iterable[Int] => Int
}
The Container
is a type which gets reduce to further corresponding types as under –
Container[String]
-> Char
Container[Array[Int]]
-> Int
, andContainer[List[Double]]
-> Double
Match types are a very powerful and also provides support for recursive definition. See the example below –
import scala.compiletime.ops.int.%
type HCF[A <: Int, B <: Int] <: Int = B match {
case 0 => A
case _ => HCF[B, A % B]
}
Here the HCF type is of a Singleton Type. Singleton Type are the types which are instantiated with exactly one value. So you have a HCF type and then create its object as –
val hcf: HCF[10, 20] = 10
Here we have defined a value which carries the highest common factor of two numbers 10 & 20.
But if you try to change the value to something else, you should see the compilation error.
The below statement will lead to compilation error-
val hcf: HCF[10, 20] = 11
// you should see error..
val hcf: HCF[10, 20] = 11
| ^^
| Found: (11 : Int)
| Required: (10 : Int)
This is because value hcf
is of type 10 which is a singleton type and thus exactly have one value.
Match types can also detect infinite loop if it is defined as an endless recursion. The compiler internally detects it by stack overflows. If there is a stack overflow, it will be taken as a compile-time error.
The example is available on the GitHub.
How compiler reduces the Match Type:
Semantically match type reduction is same as it is done in Match expressions.
S match {P1 => T1 ... Pn => Tn}
which can be further reduced to something as (similar with the pattern matching done in Scala 2):
s: S match {_: P1 => T1 ... _: Pn => Tn}
And it gets reduced to Ti
only when S
is of type Pi
.
The algorithm which compiler implements for match type reduction is as:
For every Pi
–
- if
S
is lower bound ofPi
i.e.S <: Pi
, then reduce toPi
. - else, check that no value
s
of typeS
should be of typePi
i.eS
andPi
are disjoint. - And if the check fails, then follow the same procedure for
(Pi+1)
.
References:
