Reputation: 8434
Scala defines a type called Nothing
that is a sub-type of all types. Is it possible to define our own "bottom types" that should be at the bottom of an inheritance tree that extends from a given super-type?
For example, suppose I have some type Foo
, and I want to say Xyzzy
should be at the bottom of Foo
's inheritance tree - in other words, it should inherit from anything that inherits from Foo. If we introduce a new type Bar
, and Bar <: Foo
, then Xyzzy <: Bar
. I'm basically looking for a way to say class Xyzzy isBottom Foo { ... }
. Is there any way to achieve this directly, or indirectly achieve this effect?
Upvotes: 3
Views: 169
Reputation: 39356
I mean you could do this
trait Foo
abstract final class Xyzzy extends Foo
implicit def XyzzyIsBottom[A <: Foo]: Xyzzy <:< A = null
// Example usage
class X extends Foo
def xyzzyToX(x: Xyzzy): X = x
Upvotes: 0
Reputation: 35970
It is possible to come close to the idea you're looking to do. This is not a general "bottom" type for all types in an inheritance chain. Instead, it's a bottom type specific to traits that use generics. You need to reuse Nothing
in the type definition within the inheritance structure. Take a look at List[_]
to see how they've defined Nil
:
case class ::[A](value: A, next: List[A]) extends List[A]
case object Nil extends List[Nothing]
Hence, Nil
is a List[A]
for all A
because the type parameter of list is defined as List[+A]
.
Upvotes: 1
Reputation: 5020
This doesn't work:
class Foo
abstract final class Xyzzy extends Foo
class Bar extends Foo
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> typeOf[Xyzzy] <:< typeOf[Foo]
res0: Boolean = true
scala> typeOf[Xyzzy] <:< typeOf[Bar]
res1: Boolean = false
It appears that Nothing
is handled specially by the compiler.
Upvotes: 0