2016-09-09 3 views
9

Ich baue eine Aggregation Rahmen mit einigem Code, wie diesWarum ist dieser Scala-Code nicht vom Typ abgeleitet?

trait Aggregate[T <: Aggregate[T, K], K] { self: T => 
    def plus(another: T): T 

    def show: K 
} 

Ich Paar wie dies von Aggregationen haben aussieht,

case class Count(value: Long = 1) extends Aggregate[Count, Long] { 
    def plus(another: Count) = Count(value + another.value) 

    def show = value 
} 

Sobald ich eine Aggregation definieren, die so ist,

case class By[T <: Aggregate[T, K], K, G](values: HashMap[G, T]) extends Aggregate[By[T, K, G], Map[G, K]] { 
    override def plus(another: By[T, K, G]): By[T, K, G] = By(values.merged(another.values){case ((k1,v1), (k2,v2)) => (k1, v1 plus v2)}) 

    override def show: Map[G, K] = values.map{case (k,v) => k -> v.show} 
} 

object By { 
    def apply[T <: Aggregate[T,K], K, G](key:G, value:T):By[T, K, G] = By(HashMap(key -> value)) 
} 

Ich kann so etwas nicht schreiben

By("key1", Count(100)) 

Stattdessen hatte ich dieses den Long Teil herauszufinden

By[Count, Long, String]("key1", Count(100)) 

Seit seiner nicht zu schreiben, ich hasse diese Typen zu geben, gibt es eine sauberere Weg, das zu erreichen? Ich

Antwort

4

Trick gelernt:

object By { 
    def apply[T <: Aggregate[T,K], K, G](key:G, value:T with Aggregate[T,K]):By[T, K, G] = By(HashMap(key -> value)) 
} 

Die with Aggregate[T,K] Verfeinerung hilft irgendwie die Compiler Figur aus den Typen.

+0

Wow, genial, es funktioniert wie Charme. –

+0

Wert ist technisch ein [Verbindungstyp] (http://docs.scala-lang.org/tutorials/tour/compound-types). –

+0

Idealerweise sollte es es nicht brauchen, da ich 'T' sagte, erweitern 'Aggregate [T, K] '. Kann eine technische Einschränkung im Vereinheitlichungsalgorithmus sein, die ich nicht sehen kann. –

4

Ich empfehle die Klassen Monoid und Show zu verwenden. Vielleicht möchten Sie sogar Kätzchen (Entschuldigung, haben nicht genug rep, um einen anderen Link hinzufügen, nur Google "scala Kätzchen Ableitung") automatisch die Monoid und Show Instanzen für Ihre Fall Klassen abzuleiten.

+0

Wenn Sie nicht mit diesem Muster vertraut sind hier ist ein bearbeiteter Beispiel http://tpolecat.github.io/2013/10/12/typeclass.html – tpolecat

+0

Dank Paul, Das primäre Problem, dass ich gerade jetzt konfrontiert bin ich will um diese Halbgruppen in einen Schlüsselwertspeicher zu serialisieren und ich weiß nicht, welche Semigruppeninstanz es zur Kompilierzeit ist. Also wollte die Semigruppe selbst polymorph sein und die binäre Operation haben (ich könnte die Typklasse Semigruppe zusammen mit ihr beibehalten). –

Verwandte Themen