Perché non è possibile avere i parametri di tipo nei metodi di fabbrica riportati di seguito?Scala Array mappa restituisce ArraySeq
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FunSuite
@RunWith(classOf[JUnitRunner])
class WhyScalaNeverWillMakeIt extends FunSuite {
test("Array becomes ArraySeq when you least want it") {
val arr = Array("A", "B", "C")
def f: String => Dummy = new Dummy(_)
val bucket = new Bucket[Dummy](arr.map(f))
// val bucket2 = Bucket[String, Dummy](arr, f)
// val bucket3 = Bucket[Dummy](arr, f)
val bucket4 = Bucket(arr, f)
}
class Bucket[T](val arr: Array[T]) {/* Loads of business logic */}
object Bucket {
// def apply[T, U](arr: Array[T], f:T=>U):Bucket[U] = new Bucket[U](arr.map(b => f(b)))
// def apply[T](arr: Array[String], f:String=>T):Bucket[T] = new Bucket[T](arr.map(b => f(b)))
def apply(arr: Array[String], f:String=>Dummy):Bucket[Dummy] = new Bucket[Dummy](arr.map(f))
}
class Dummy(val name: String)
}
Se Decommentare i metodi di fabbrica in object Bucket
ottengo:
error: type mismatch;
found : scala.collection.mutable.ArraySeq[T]
required: Array[T]
def apply[T](arr: Array[String], f:String=>T):Bucket[T] = new Bucket[T](arr.map(b => f(b)))
In qualche modo il compilatore Scala po 'confusa (o sono io ;-)?), Quando ho introdotto il parametro di tipo T. Forse Sto facendo qualcosa di molto sbagliato qui, ma non riesco a capire perché l'introduzione di un parametro di tipo significhi che la funzione mappa debba cambiare il tipo di ritorno da Array [T] a ArraySeq [T].
So che Array è solo un wrapper attorno a Java Array e che probabilmente dovrei usare una delle classi di Scala più fantasiose, come Seq o List, ma che comunque non spiega questo comportamento piuttosto strano.
Qualcuno può spiegare perché questo sta accadendo e forse anche come risolverlo (usando ancora gli Array)?
Edit: sto usando Scala 2.9.1
OK, grazie Sergey, che ha fatto il trucco. Ora devo solo leggere e capire i collegamenti che hai fornito. Forse c'è qualcosa che mi farà accettare la brutta sintassi ++ con [T: ClassManifest]. – Jorgen
So cosa può farti accettare quella sintassi, vedere a cosa serve desugars: def foo [T: Bar] diventa def foo [T] (implicito generateName: Bar [T]) –