Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot prove that Null <:< T

Tags:

scala

optional

In my Scala code, I have an array of Option[T], like so:

val items = Array.fill[Option[T]](10)(None)

Now, I want to read a specific item from that array; if it has not been set, I want to have null. But when I do items(desiredIndex).orNull, the Scala compiler yells at me:

Error:(32, 34) Cannot prove that Null <:< T.
      (items(desiredIndex).orNull).asInstanceOf[T]

I don't fully understand this error. What I do understand is that the compiler cannot infer that null is indeed a valid value for T (since it is not known what T will be). Looking at the implementation, I should supply implicit evidence for the fact that null is a valid value for T:

@inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)

Now, my question is: how can I supply such evidence? What type is ev supposed to be, and how can I create a value for it?

like image 978
mthmulders Avatar asked Jul 06 '16 20:07

mthmulders


2 Answers

By a type bound:

scala> def f[T >: Null : ClassTag]: T = {
     | val items = Array.fill[Option[T]](10)(None)
     | items(0).orNull }
f: [T >: Null](implicit evidence$1: scala.reflect.ClassTag[T])T

scala> f[String]
res3: String = null

Per Pedro:

scala> def f[T >: Null]: T = Array.fill[Option[T]](10)(None).apply(0).orNull
f: [T >: Null]=> T
like image 84
som-snytt Avatar answered Oct 06 '22 21:10

som-snytt


While the solution given by som-snytt is simpler and better for this specific case, to answer the questions directly:

What type is ev supposed to be

Null <:< A1 (this is just a different way to write <:<[Null, A1]).

and how can I create a value for it

For a specific type you don't need to, the compiler will provide this evidence itself (using scala.Predef.$conforms). But when working with a generic T, you can just add the same implicit parameter to your method (or, for <:< specifically, a type bound), and to methods calling it, etc. until you come to a specific type.

like image 25
Alexey Romanov Avatar answered Oct 06 '22 23:10

Alexey Romanov