Sto cercando di ridimensionare un po 'di codice e ho dovuto lavorare con tipi di tipo più alto. Il seguente esempio minimale funziona bene:Le informazioni di tipo vengono perse quando si lavora con oggetti di tipo alto in Scala
trait Builder[M[_]] {
def build[A]: M[A]
def buildPair[A, B]: (M[A], M[B]) = (build[A], build[B])
}
class List[A]
class BuilderList extends Builder[List] {
def build[A] = new List[A]
}
val l: List[String] = (new BuilderList).build[String]
val ll: (List[String], List[Double]) = (new BuilderList).buildPair[String, Double]
defined trait Builder
defined class List
defined class BuilderList
l: List[String] = [email protected]
ll: (List[String], List[Double]) = ([email protected],[email protected])
Se ora voglio applicare questo a un tipo con due argomenti di tipo, diciamo
class Map[K, V]
Vorrei essere in grado di scrivere
trait BuilderMap[K] extends Builder[Map[K, _]] {...}
ma ovviamente questo non funziona perché gli argomenti di tipo in Scala non sono al curry.
Ho trovato che il seguente trucco mi ha permesso di passare la compilazione:
trait PartialApplier[F[_, _], K] {
type PartiallyApplied[_] = F[K, _]
}
class BuilderMap[K] extends Builder[PartialApplier[Map, K]#PartiallyApplied] {
def build[V] = new Map[K, V]
}
Ma poi, qualche effetto di strano accade e non riesco a capire il motivo per cui:
scala> val m: Map[Int, String] = (new BuilderMap[Int]).build[String]
m: Map[Int,String] = [email protected]
scala> val mm: (Map[Int, String], Map[Int, Double]) = (new BuilderMap[Int]).buildPair[String, Double]
<console>:21: error: type mismatch;
found : (Map[Int, _], Map[Int, _])
required: (Map[Int,String], Map[Int,Double])
val mm: (Map[Int, String], Map[Int, Double]) = (new BuilderMap[Int]).buildPair[String, Double]
Sembra che le funzioni definite nel tratto di tipo superiore Builder
perdano alcune informazioni di tipo quando utilizzo il trucco .
C'è un modo per rendere tutto questo perfettamente funzionante? Forse il trucco PartialApplier
non è la strada giusta da percorrere!
Questo è un perfetto risposta. Grazie! – jrjd