6

In Scala 2.11.2, the following minimal example compiles only when using type ascription on the Array[String]:

object Foo {    

  def fromList(list: List[String]): Foo = new Foo(list.toArray : Array[String])   

}

class Foo(source: IndexedSeq[String])    

If I remove the type ascription in fromList, it will fail to compile with the following error:

Error:(48, 56) polymorphic expression cannot be instantiated to expected type;
 found   : [B >: String]Array[B]
 required: IndexedSeq[String]
  def fromList(list: List[String]): Foo = new Foo(list.toArray)
                                                       ^

Why can't the compiler infer the Array[String] here? Or does this issue have to do something with the implicit conversion from Array's to IndexedSeq's?

Chris
  • 2,057
  • 2
  • 16
  • 20
  • 1
    Note I think you can do: `object Foo { def fromList(list: List[String]): Foo = new Foo(list.toArray[String])}` instead. – Dave L. Oct 31 '14 at 15:38
  • Or just `list.toIndexedSeq`, of course. The question's still a good one, though. – Travis Brown Oct 31 '14 at 15:41
  • Thanks for pointing that out. The reason I'm going for `Array`s instead of `IndexedSeq`s is purely for performance reasons. I had to profile the function and found that `Vector`s take more overhead when creating lots of small instances. – Chris Oct 31 '14 at 15:48

1 Answers1

4

The issue is that the .toArray method returns an Array of some type B which is a superclass of the T in List[T]. This allows you to use a list.toArray on List[Bar] where an Array[Foo] is required if Bar extends Foo.

Yes, the real reason this doesn't work out of the box is that the compiler is trying to figure out which B to use and also how to get to an IndexedSeq. It seems like it's trying to resolve the IndexedSeq[String] requirement but B is only guaranteed to be a String or a superclass of String; hence the error.

This is my preferred work around:

def fromList(list: List[String]): Foo = new Foo(list.toArray[String])
Nate
  • 2,205
  • 17
  • 21