Array[T].map results in ArraySeq

75 views
Skip to first unread message

boris....@gmail.com

unread,
Jun 23, 2016, 4:14:44 PM6/23/16
to scala-user
I've just discovered that Array[T].map results in an ArraySeq. I feel that Array.map should result in an Array, but at least there should be an implicit conversion to Array. Is this a bug?

According to the API doc, map has type

def map[B](f: (A) ⇒ B): Array[B]


case class Foo[T](a: Array[T]) {
    def foo(f: T => T) = Foo(a map f)
}

type mismatch;  found   : scala.collection.mutable.ArraySeq[T]  required: Array[?]   

Adriaan Moors

unread,
Jun 23, 2016, 6:34:52 PM6/23/16
to boris....@gmail.com, scala-user
Array's CBF needs a ClassTag, so you'll need to provide it -- for example, as follows:

import scala.reflect.ClassTag

case class Foo[T: ClassTag](a: Array[T]) {

def foo(f: T => T) = Foo(a map f)
}
One way to discover this is using IntelliJ's "Implicit parameters" action on a concrete example
Array(1,2,3).map(x => x)

Screenshot 2016-06-23 15.33.20.png





--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

boris....@gmail.com

unread,
Jun 24, 2016, 4:27:49 PM6/24/16
to scala-user, boris....@gmail.com
What is a class tag and why is it needed?

The explanation in the Scala API doesn't help me: "This is particularly useful for instantiating Arrays whose element types are unknown at compile time." My Array has type T and this is known at compile time.

Rex Kerr

unread,
Jun 24, 2016, 4:41:48 PM6/24/16
to boris....@gmail.com, scala-user
But you just said you _didn't_ know what type T was.  That's why it's a parameter.  Eventually you will know the type, but when you compile the case class code you don't know what it is.

If Scala used a templating mechanism like C++, instead of a generics mechanism like Java, this wouldn't matter: you'd generate the known-T-appropriate code at compile time.  Downside: vast amounts of code is generated which all does basically the same thing.  With generics, the decision of how to implement the details is deferred to runtime, and because of erasure it doesn't actually know what the type is any more.  Downside: you need to give it something else to retain that information at runtime.  Hence the ClassTag.

  --Rex


On Fri, Jun 24, 2016 at 1:27 PM, <boris....@gmail.com> wrote:
What is a class tag and why is it needed?

The explanation in the Scala API doesn't help me: "This is particularly useful for instantiating Arrays whose element types are unknown at compile time." My Array has type T and this is known at compile time.

--

boris....@gmail.com

unread,
Jun 24, 2016, 5:54:58 PM6/24/16
to scala-user, boris....@gmail.com
So does this have to do with Java's type erasure? And why does List[T].map give a List without the need for a class tag? Are class tags for Arrays only?

It works in Ocaml and F#:
let foo f a = Array.map f a
val foo : ('a -> 'b) -> 'a array -> 'b array = <fun>

Rex Kerr

unread,
Jun 24, 2016, 6:36:03 PM6/24/16
to boris....@gmail.com, scala-user
Arrays are not erased; everything else is.  Yes, it's kind of weird.

You can read more about generics, erasure, and arrays online, e.g. at http://code.stephenmorley.org/articles/java-generics-type-erasure/


Reply all
Reply to author
Forward
0 new messages