Scala

2015-09-01 18 views
6

Yüksek çeşitliliğe sahip nesnelerle çalışırken tür bilgileri kayboluyor Bazı kodları etkisiz hale getirmeye çalışıyorum ve daha yüksek türdeki türlerle çalışmak zorunda kaldım. Aşağıdaki minimum örnek çalışıyor: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]) 

Şimdi iki tip argümanlarla bir türe bu uygulamak istiyorsanız,

class Map[K, V] 

Ben yazabilmek istiyorum demek

trait BuilderMap[K] extends Builder[Map[K, _]] {...} 

Ancak elbette bu çalışmaz, çünkü Scala'daki tür argümanları körlenmez.

trait PartialApplier[F[_, _], K] { 
    type PartiallyApplied[_] = F[K, _] 
} 

class BuilderMap[K] extends Builder[PartialApplier[Map, K]#PartiallyApplied] { 
    def build[V] = new Map[K, V] 
} 

Ama sonra, bazı garip etkisi olur ve neden sebebini bilemiyorum:

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] 

görünüyor

aşağıdaki hile beni derleme geçmesine izin bulundu Builder'un üst düzey özelliğindeki işlevlerin, PartialApplier numarasını kullandığımda bazı tür bilgileri kaybettiğini.

Tüm bunların sorunsuz bir şekilde birlikte çalışmasının bir yolu var mı? Belki de PartialApplier hilesi gitmek için doğru yol değildir!

cevap

4

Örneğinizde type PartiallyApplied[_] = F[K, _]'da alt çizgi aynı tür belirtmez. Bir mükemmel Yani

class BuilderMap[K] extends Builder[({ type L[V] = Map[K, V] })#L] { 
    def build[V] = Map.empty[K, V] 
} 
+0

:

O size hiç PartialApplier kullanmaktan kaçının ve bunun gibi Builder türü parametresi tanımlayabilir, sen PartialApplier

olarak
trait PartialApplier[F[_, _], K] { type PartiallyApplied[V] = F[K, V] } 

Ayrıca tanımlarsanız, işleri Cevap. Teşekkürler! – jrjd