Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Misunderstanding with type checks in Scala

Tags:

scala

I have simple type hierarchy in Scala:

trait A {
    trait A1
}

object B extends A {
    case object B1 extends A1
}

object C extends A {
    case object C1 extends A1
}

And, I'm gonna use these types like that:

def get(): Any = C.C1

get() match {
    case _: B.A1 => println("B")
    case _: C.A1 => println("C")
    case _: A#A1 => println("Any")
}

Surprisingly, I'm getting B printed (I've expected C).

Why compiler treats C.C1 as instance of B.A1?

like image 791
Dmitry Bespalov Avatar asked Oct 15 '15 12:10

Dmitry Bespalov


People also ask

What are the different types of Scala pattern matching?

Following are the different types of Scala Pattern Matching, let’s discuss them one by one: a. Variable Patterns An identifier for a variable pattern begins with a lowercase letter. It matches a value and binds to it the variable name. The wildcard pattern ‘_’ is a special case of this. b. Typed Patterns

What is typetag in Scala?

TypeTag The Scala reflection API has a mechanism called TypeTag that allows you to inspect the type of instances, including the types of generics, at runtime. As the docs, state “TypeTags can be thought of as objects which carry along all type information available at compile time, to runtime”.

Can we replace if-else ladders with pattern matching in Scala?

Not only we can use it to replace if-else ladders also we can use it to deconstruct a value into its constituent parts. Scala pattern matching is made of constants, variables, constructors, and type tests. Using such a pattern, we can test if a value follows a pattern. We can only bind a variable name once in a pattern.

Is there an alternative to try/success/failure in Scala?

In the meantime, see the scala.util.Try documentation for more information. (One thing you should get from this example is that Try/Success/Failure is an alternative to using Option/Some/None.


1 Answers

This is a known bug.

Scalac does generate a warning for this using the -unchecked flag:

warning: The outer reference in this type test cannot be checked at run time.
            case _: B.A1 => println("B")
                  ^

So right now, B.A1 and C.A1 appear the same to the compiler in the pattern match, because it doesn't check the outer reference to B or C.

See this related discussion.

And SI-4440

like image 99
Michael Zajac Avatar answered Oct 01 '22 17:10

Michael Zajac