Ich versuche, etwas Code zu faktorisieren und am Ende mit höher-kinded Typen arbeiten musste. Die folgende minimal Beispiel funktioniert:Typ Informationen verloren gehen, wenn mit hoch-kinded Objekte 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])
Wenn ich jetzt dies mit zwei Typargumente auf einen Typ angewendet werden soll, sagen
class Map[K, V]
Ich möchte in der Lage sein zu schreiben
trait BuilderMap[K] extends Builder[Map[K, _]] {...}
aber das funktioniert natürlich nicht, weil Typ Argumente in Scala nicht curried sind.
fand ich, dass der folgende Trick erlaubte mir Kompilation weitergeben müssen:
trait PartialApplier[F[_, _], K] {
type PartiallyApplied[_] = F[K, _]
}
class BuilderMap[K] extends Builder[PartialApplier[Map, K]#PartiallyApplied] {
def build[V] = new Map[K, V]
}
Aber dann einige seltsame Wirkung geschieht, und ich kann den Grund nicht erklären, warum:
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]
Es scheint, dass die Funktionen, die in dem höher-kinded Merkmal Builder
definiert sind, einige Typeninformation verlieren, wenn ich den Trick PartialApplier
verwende.
Gibt es eine Möglichkeit, all dies reibungslos zusammen zu arbeiten? Vielleicht ist der PartialApplier
Trick nicht der richtige Weg!
Das ist ein perfekt Antworten. Vielen Dank! – jrjd