Are there any plans to start supporting union types, similarly to how it’s done in Dotty (e.g., Int | Long | Float | Double
)? If yes, is there any time estimate?
If not, what would be the best way to implement the following functionality in Scala 2.12?
Suppose we are interacting with a native C++ library supporting both Float32 (i.e., Float
) and Float64 (i.e., Double
) data types. We want to define a DataType
trait in our library, subclassed by DataType.Float32
and DataType.Float64
that implement functionality such as casting for example. In that trait we want to have an abstract type T
, which the DataType.Float32
will override with value Float
and DataType.Float64
will override with value Double
. In that trait we also define a couple methods:
def cast[V <: Float | Double](value: V): T
def setElementInBuffer(buffer: ByteBuffer, index: Int, value: T): Unit
def getElementFromBuffer(buffer: ByteBuffer, index: Int): T
T here can only be either Float
or Double
, but the compiler does not know that. Let’s say we read from one buffer of some data type, cast the elements, and write in a buffer of the other data type. Ideally we want cast to be specialized for the primitives. For type V
, above, the constraint can be enforced by something like the solution of Miles Sabin.
However, currently there is no way to make the compiler aware that T
can only be Float
or Double
. We could use a witness-style inheritance-based pattern, but that would force boxing of the primitive values and thus be inefficient. Defining type T <: Float | Double
(like in Dotty) would be ideal. Is there a way to mimic that behavior currently in Scala, without boxing the primitives?
Note that paraneterizing the DataType trait with T
and having a context bound there does not work. The reason is this: suppose a class Tensor has a data type but holds a reference to a C++ Tensor with an integer representing its data type. Then the way we obtain the data type is by calling a JNI function that returns that integer which we then convert to a DataType[_]
. This makes the compiler unable to verify that one tensors data type returns elements that can be fed into another tensor’s buffer (after casting to the appropriate type).
I hope this application description is sufficient for understanding the problem, but I can provide more details if necessary.
Thank you!