Le code Scala suivant fonctionne:Comment paramètre de type « extrait » instancier une autre classe
object ReducerTestMain extends App {
type MapOutput = KeyVal[String, Int]
def mapFun(s:String): MapOutput = KeyVal(s, 1)
val red = new ReducerComponent[String, Int]((a: Int, b: Int) => a + b)
val data = List[String]("a", "b", "c", "b", "c", "b")
data foreach {s => red(mapFun(s))}
println(red.mem)
// OUTPUT: Map(a -> 1, b -> 3, c -> 2)
}
class ReducerComponent[K, V](f: (V, V) => V) {
var mem = Map[K, V]()
def apply(kv: KeyVal[K, V]) = {
val KeyVal(k, v) = kv
mem += (k -> (if (mem contains k) f(mem(k), v) else v))
}
}
case class KeyVal[K, V](key: K, value:V)
Mon problème est que je voudrais instancier ReducerComponent
comme ceci:
val red = new ReducerComponent[MapOutput, Int]((a: Int, b: Int) => a + b)
ou mieux encore:
val red = new ReducerComponent[MapOutput](_ + _)
Cela signifie beaucoup de choses:
- Je voudrais saisir vérifier que
MapOutput
est du typeKeyVal[K, C]
, - Je veux saisir vérifier que
C
est le même type utilisé dansf
, - Je dois aussi « extraire »
K
afin d'instanciermem
, et de vérifier les paramètres deapply
.
Est-ce beaucoup à demander? :) Je voulais écrire quelque chose comme
class ReducerComponent[KeyVal[K,V]](f: (V, V) => V) {...}
Au moment où j'instancier ReducerComponent
tout ce que j'ai est f
et MapOutput
, donc infère V est OK. Mais alors j'ai seulement KeyVal[K,V]
comme un paramètre de type d'une classe, qui peut être différent de KeyVal[_,_]
.
Je sais ce que je demande est probablement fou si vous comprenez comment l'inférence de type fonctionne, mais je ne le fais pas! Et je ne sais même pas ce qui serait une bonne façon de procéder - à part de faire des déclarations de type explicites tout le long de mon code de haut niveau. Devrais-je simplement changer toute l'architecture?
il pourrait être préférable de définir 'trait KeyValAux [KK, VV] {type K = KK; type V = VV; tapez KV = KeyVal [K, V]} 'pour rendre la définition de' MapOutput' un peu plus agréable: 'type MapOutput = KeyValAux [String, Int]' – dk14
Ensuite, il n'y a plus moyen d'écrire 'ReducerComponent.apply'. Mais nous pourrions écrire une sous-classe qui fait cela. – gzm0