score:13

This is no bug. `Array` is not covariant. B being a subtype of B does not make Array[B] a subtype of Array[A]. This is contrary to java, where B[] is a subtype of A[], which is unsound:

``````A[] b = new B[1];
b[0] = new (A);
-> ArrayStoreException
``````

So your Array[Some[Any]] is not an Array[Option[Any]]. You must make sure you have an Array[Option], which you may do with

``````val row2 = Array[Option[Any]](Some(test2), Some(12345))
``````

You can also use a type abscription on one of the item:

``````val row2 = Array(Some(test2): Option[String], Some(12345))
``````

Or if you know your values are non-null,

``````val row2 = Array(Option(test2), Option(12345))
``````

(It's enough to do that on one of the value)

`List`, on the other hand is covariant, which is why it works.

It is actually unfortunate that the more precise type `Some` is inferred, it is quite uncommon that you want the type of something to be known as `Some` (or `None`) rather than `Option`.

Edit Sorry, looks like I completely missed the point, about why there are different. `Array` is not covariant, but Iterable is. So it would seems that `Array[B]` while not being an `Array[A]`, should be an `Iterable[A]`, then everything should work. It would be so if Array was a subtype of Iterable. It is not, it comes with the JVM, cannot be made to extend `Iterable`. What there is is an implicit conversion to `WrappedArray`, which is an `Iterable`.

When you write `val l = List(row1, row2)`, it has no reason to apply this conversion. It types list as precisely as it can. Then the fact that List is covariant (a List[B] is a List[A] if B is an A) will not kick in when we have not B is an A, but B has an implicit conversion to A.

On the other hand, when you write val l: List[Iterable[A]] = List(x,y) then the List(...) function expects Iterable[A] arguments, and at this point it looks for implicit conversions.

Still not a bug, but trickier than I thought. Maybe you could do a

``````class Container[T <% Iterable[Option[Any]]](val rows: Iterable[T])
``````

score:3

In first case, the type of `listtest` is inferred from its definition: `List[Array[Some[Any]]]`. @didierd explains why this is not a suitable type for the argument of `Container` constructor.

In second case, the type argument of `List(row1,row2)` is inferred from the fact it's used as the constructor argument.

score:3

Your problem is with implicit conversions. Scala does not try to apply implicit conversions for type parameters for 'contained types'.

Array is a not an Iterable, so if you were to use

``````val row1 = List(Some("test2"), Some(12345))
``````

this works. But you're using Array, so it should try to find an implicit conversion for Array -> Iterable (which does exist), but it does not try. I'll try and find a better reference for this, but in the meantime, you can see this question.

If you explicitly specify as an Iterable the type of row, then this works, because the type inferencing works.

``````val row1: Iterable[Option[Any]] = Array(Some("test2"), Some(1234))
``````

score:4

I tried your code and there was the same exception. Then I replaced

``````scala> val listtest = List(row1, row2)
``````

on

``````scala>  val listtest: Iterable[Iterable[Option[Any]]] = List(row1, row2)
listtest: Iterable[Iterable[Option[Any]]] = List(WrappedArray(Some(test), Some(1234)), WrappedArray(Some(test2), Some(12345)))
``````

and it worked fine:

``````scala> val test = new Container(listtest)
test: Container = Container@a75974
``````