Reputation: 353
Consider two classes A and B:
// A.scala
object A {
sealed abstract class Nat
case object Zero extends Nat
case class Succ(n : Nat) extends Nat
def pp(n : Nat) = n match {
case Zero => println("Zero")
case Succ(m) => println("Succ")
case _ => println("WTF")
}
def main(args : Array[String]) =
pp(B.f())
}
// B.java
public class B {
static A.Nat f() {
return new A.Nat() {};
}
}
Compile, run:
$ scala A
WTF
As said in the documentation, "A sealed class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class."
I thought it implies pattern-matching through subclasses defined in the same file is enough to cover all cases, but as we can see from this example it's not true.
Here is a question: is there a way to write really sealed classes (like ADTs) or I need to write dummy last case in every pattern match to ensure code safety?
Upvotes: 1
Views: 210
Reputation: 2832
It's possible to create them from Java as the detail that a Scala class is sealed is only honoured by the Scala compiler itself. The Java compiler has no concept that A.Nat is sealed at all.
Also as a side note, you'll need to mark Succ as sealed, as otherwise even in Scala someone can extend it.
Upvotes: 4