Cannot prove that Null <:< T - scala

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?

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

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.

Related

Scala upper and lower type bound

I'm having trouble finding a way in scala to simultaneously impose an upper and lower type bound. I need to make a generic function where the type parameter is both hashable (subtype of AnyRef) and nullable (supertype of Null).
I could achieve the former like this:
def foo[T <: AnyRef](t: T) = ???
And the latter like this:
def bar[T >: Null)(t: T) = ???
Is there a way that I can do both simultaneously? Thanks.
What about this?
def foo[T >: Null <: AnyRef](t: T) = ???
It should work. That is:
foo(42) // does not compile
foo(null) // compiles
foo("hello") // compiles
Any type that is a subclass of AnyRef can be assigned the value null, so you do not need the upper bound.
def foo[T <: AnyRef](x: T) = x
foo(null) // returns null
That said, since you need to be able to hash the value, it should be noted that if you attempt to dereference null (e.g. null.hashCode) you will get a NullPointerException. For example:
def foo[T <: AnyRef](x: T) = x.hashCode
foo(null) // Throws an NPE
Furthermore, any use of null in Scala programs is strongly discouraged. Bearing all that in mind, I think what you might really want is something like this, which works for any type:
def foo[T](x: Option[T]) = x.hashCode
def foo(None) // Works. None is equivalent to no value (and Option(null) == None).
def foo(Some(1)) // Works. Note an Int isn't an AnyRef or nullable!
def foo(Some("Hello, world!")) // Works
def foo(Option(null)) // Works.
def foo(Option(z)) // Works, where z can be any reference type value, including null.
Option[T] is a functional means of dealing with undefined values (such as nullable types), and it works for any type T.

Scala type inference and multiple arguments list

(Scala 2.11.8)
Consider the following code:
trait Class[A] {
def f1[B >: A](arg1: Int)(ord: Ordering[B]): Int
def f2[B >: A](arg1: Int, ord: Ordering[B]): Int
def f[B >: A](ord: Ordering[B]): Int = {
f1(123)(ord) // Compilation error!
f2(123, ord) // OK
}
}
Here, line f1(123)(ord) raises type mismatch; found : Ordering[B] required: Ordering[A] Note: B >: A, but trait Ordering is invariant in type T. You may wish to investigate a wildcard type such as _ >: A. (SLS 3.2.10)
If we change the call to f1[B](123)(ord), error disappears.
Why does the presence of multiple arguments list confuses the typechecker? Is this a bug, or an expected result?
It's not a bug - the separation into parameter lists means that the type parameter is inferred based on the first argument list alone:
f1(123)(ord)
can be rewritten as:
val partiallyApplied = f1(123)
partiallyApplied(ord)
Now - what is partiallyApplied's type? Since the type parameter wasn't explicitly set, and there's no argument / return type to use for inference, the type parametter is inferred to be A (there's no specific B yet! So partiallyApplied's type is (Ordering[A]) => Int), hence using it with Ordering[B] later gives the exception.
In contrast, when calling:
f2(123, ord)
Since ord has type Ordering[B], the type parameter can be inferred to be B, hence compilation succeeds.

LUB of List of Invariant Class's Instances

Given a class with a covariant type parameter:
scala> class G[+A]
defined class G
The following list shows a Least Upper Bound of List[G[Any]].
scala> List(new G[Int], new G[String])
res1: List[G[Any]] = List(G#5aa360ea, G#6548bb7d)
Then, given a class with an invariant type parameter:
scala> class F[A]
defined class F
I see a Least Upper Bound (LUB) of List[F[_ >: String with Int]].
scala> List(new F[Int], new F[String])
res0: List[F[_ >: String with Int]] = List(F#6c4980d3, F#327bcebd)
A simpler example shows a LUB of List[Any]:
scala> List( (42 : Int), "foobar" )
res2: List[Any] = List(42, foobar)
Please explain the LUB of the List of F's.
G is covariant over its type parameter A. This means that given any types A and B, if A is a sub-type of G, then G[A] is a sub-type of G[B]. Let's write this in short-hand to using A <:< B to denote that A is a sub-type of B, then G[A] <:< G[B].
This means that when we have a List(new G[Int], new G[String]), the compiler is allowed to infer it as a List[Any], because List[G[Int]] <:< List[G[Any]] and List[G[String]] <:< List[G[Any]] (since List is also covariant over its type parameter).
You probably already know that, but it's worth explaining for those that don't yet.
F is invariant over its type parameter A, so we cannot make the same deductions. Okay, so then what is the type of List(new F[Int], new F[String]) ? Because F is invariant, we cannot say that F[Int] <:< F[Any] or that F[String] <:< F[Any] (because it's not true!). So it's not a List[F[Any]].
So what can the compiler infer? It's only real choice is some existential type, because it cannot be Any, or String with Int, or anything else without breaking covariance. Since it is looking for the least upper-bound, it infers an existential type that is bounded below by the compound of the contained types (in F). That is, _ >: String with Int is some nameless type that has a lower-bound of String with Int.
Or, in other words, we know we have a List of Fs, but we don't know what type is contained in each of them. Only that any given F in the List is an F[Int], or a F[String], but that's it.

Why Process0 is not defined as Process[Id, O]

sealed trait Process[+F[_], +O]
/**
* Created by pach on 11/07/14.
*/
package object stream {
type Process0[+O] = Process[Nothing,O]
...
}
This is how Process0 defined.
Actually I cannot understand why this compiles, because Nothing takes no type param.
To represent a stream with no effect
why not just set the context type F to value type itself(using identity type constructor, scalaz.Scalaz.Id).
type Process0[+O] = Process[Id, O]
Scala compiler treats Nothing a bit differently than other types, e.g the same trick won't work with Null, although it's a bottom type for all reference types. You can check subtype relationship using implicits and special method <:<, like this:
scala> implicitly[Nothing <:< List[_]]
res1: <:<[Nothing,List[_]] = <function1>
And if there is no relationship you'll see:
scala> implicitly[Null <:< Int]
<console>:8: error: Cannot prove that Null <:< Int.
implicitly[Null <:< Int]
As for your main question, i'm not that familiar with scalaz-streams, but as i understand type Id is just a type itself, i.e type Id[A] = A, so if you had Process[Id, O], this would mean that you have some non-effectful input which gives some output. But in case of Process0 there shouldn't be any input at all, it should only generate some output.

what's different between <:< and <: in scala

I already know that:
<: is the Scala syntax type constraint
while <:< is the type that leverage the Scala implicit to reach the type constrait
for example:
object Test {
// the function foo and bar can have the same effect
def foo[A](i:A)(implicit ev : A <:< java.io.Serializable) = i
foo(1) // compile error
foo("hi")
def bar[A <: java.io.Serializable](i:A) = i
bar(1) // compile error
bar("hi")
}
but I want to know when we need to use <: and <:< ?
and if we already have <:, why we need <:< ?
thanks!
The main difference between the two is, that the <: is a constraint on the type, while the <:< is a type for which the compiler has to find evidence, when used as an implicit parameter. What that means for our program is, that in the <: case, the type inferencer will try to find a type that satisfies this constraint. E.g.
def foo[A, B <: A](a: A, b: B) = (a,b)
scala> foo(1, List(1,2,3))
res1: (Any, List[Int]) = (1,List(1, 2, 3))
Here the inferencer finds that Int and List[Int] have the common super type Any, so it infers that for A to satisfy B <: A.
<:< is more restrictive, because the type inferencer runs before the implicit resolution. So the types are already fixed when the compiler tries to find the evidence. E.g.
def bar[A,B](a: A, b: B)(implicit ev: B <:< A) = (a,b)
scala> bar(1,1)
res2: (Int, Int) = (1,1)
scala> bar(1,List(1,2,3))
<console>:9: error: Cannot prove that List[Int] <:< Int.
bar(1,List(1,2,3))
^
1. def bar[A <: java.io.Serializable](i:A) = i
<: - guarantees that instance of i of type parameter A will be subtype of Serializable
2. def foo[A](i:A)(implicit ev : A <:< java.io.Serializable) = i
<:< - guarantees that execution context will contains implicit value (for ev paramenter) of type A what is subtype of Serializable.
This implicit defined in Predef.scala and for foo method and it is prove if instance of type parameter A is subtype of Serializable:
implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
fictional case of using <:< operator:
class Boo[A](x: A) {
def get: A = x
def div(implicit ev : A <:< Double) = x / 2
def inc(implicit ev : A <:< Int) = x + 1
}
val a = new Boo("hi")
a.get // - OK
a.div // - compile time error String not subtype of Double
a.inc // - compile tile error String not subtype of Int
val b = new Boo(10.0)
b.get // - OK
b.div // - OK
b.inc // - compile time error Double not subtype of Int
val c = new Boo(10)
c.get // - OK
c.div // - compile time error Int not subtype of Double
c.inc // - OK
if we not call methods what not conform <:< condition than all compile and execute.
There are definitely differences between <: and <:<; here is my attempt at explaining which one you should pick.
Let's take two classes:
trait U
class V extends U
The type constraint <: is always used because it drives type inference. That's the only thing it can do: constrain the type on its left-hand side.
The constrained type has to be referenced somewhere, usually in the parameter list (or return type), as in:
def whatever[A <: U](p: A): List[A] = ???
That way, the compiler will throw an error if the input is not a subclass of U, and at the same time allow you to refer to the input's type by name for later use (for example in the return type). Note that if you don't have that second requirement, all this isn't necessary (with exceptions...), as in:
def whatever(p: U): String = ??? // this will obviously only accept T <: U
The Generalized Type Constraint <:< on the other hand, has two uses:
You can use it as an after-the-fact proof that some type was inferred. As in:
class List[+A] {
def sum(implicit ev: A =:= Int) = ???
}
You can create such a list of any type, but sum can only be called when you have the proof that A is actually Int.
You can use the above 'proof' as a way to infer even more types. This allows you to infer types in two steps instead of one.
For example, in the above List class, you could add a flatten method:
def flatten[B](implicit ev: A <:< List[B]): List[B]
This isn't just a proof, this is a way to grab that inner type B with A now fixed.
This can be used within the same method as well: imagine you want to write a utility sort function, and you want both the element type T and the collection type Coll. You could be tempted to write the following:
def sort[T, Coll <: Seq[T]](l: Coll): Coll
But T isn't constrained to be anything in there: it doesn't appear in the arguments nor output type. So T will end up as Nothing, or Any, or whatever the compiler wants, really (usually Nothing). But with this version:
def sort[T, Coll](l: Coll)(implicit ev: Coll <:< Seq[T]): Coll
Now T appears in the parameter's types. There will be two inference runs (one per parameter list): Coll will be inferred to whatever was given, and then, later on, an implicit will be looked for, and if found, T will be inferred with Coll now fixed. This essentially extracts the type parameter T from the previously-inferred Coll.
So essentially, <:< checks (and potentially infers) types as a side-effect of implicit resolution, so it can be used in different places / at different times than type parameter inference. When they happen to do the same thing, stick to <:.
After some thinking, I think it has some different.
for example:
object TestAgain {
class Test[A](a: A) {
def foo[A <: AnyRef] = a
def bar(implicit ev: A <:< AnyRef) = a
}
val test = new Test(1)
test.foo // return 1
test.bar // error: Cannot prove that Int <:< AnyRef.
}
this menas:
the scope of <: is just in the method param generic tpye scope foo[A <: AnyRef]. In the example, the method foo have it's generic tpye A, but not the A in class Test[A]
the scope of <:< , will first find the method's generic type, but the method bar have no param generic type, so it will find the Test[A]'s generic type.
so, I think it's the main difference.