Closed
Description
Compiler version
Scala compiler version 3.0.0-RC1
Minimized code
I have made this light-weight utility for handling Empty values:
object Empty:
override def toString = "Empty"
type Empty = Empty.type
extension [T](x: T | Empty)
def toOption: Option[T] = x match
case Empty => None
case _ => Option(x.asInstanceOf[T])
def isEmpty: Boolean = x.isInstanceOf[Empty]
def nonEmpty: Boolean = !isEmpty
def get: T = x match
case Empty => (throw new NoSuchElementException("Empty.get")).asInstanceOf[T]
case _ => x.asInstanceOf[T]
def getOrElse(default: T): T = x match
case Empty => default
case _ => x.asInstanceOf[T]
Output
With this we can do nice things such as:
scala> val xs = Vector[Int | Empty](3, 4, Empty, 5)
val xs: Vector[Int | Empty] = Vector(3, 4, Empty, 5)
scala> val ys = xs.map(_.getOrElse(42))
val ys: Vector[Int] = Vector(3, 4, 42, 5)
scala> // Nice type of ys inferred - THANK YOU Scala 3 :)
But here, type inference is struggling:
scala> val xs2 = Vector[Int | String | Empty](3, "hello", Empty)
val xs2: Vector[Int | String | Empty] = Vector(3, hello, Empty)
scala> val ys2 = xs2.map(_.getOrElse("nada"))
val ys2: Vector[Matchable] = Vector(3, hello, nada)
scala> // Not so nice type of ys2 - could this become Vector[Int | String] ?
Expectation
It would be very nice if user-written union types of more than two members were preserved, and in the example above a more precise type than Vector[Matchable]
could be inferred for ys2
.