以下 Scala 代码有效:
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)
我的问题是我想像这样实例化ReducerComponent
:
val red = new ReducerComponent[MapOutput, Int]((a: Int, b: Int) => a + b)
甚至更好:
val red = new ReducerComponent[MapOutput](_ + _)
这意味着很多事情:
- 我想对类型进行类型
MapOutput
检查KeyVal[K, C]
, - 我想检查
C
是否与 中使用的类型相同f
, - 我还需要“提取”
K
以便mem
从apply
.
要问的很多吗?:) 我想写类似的东西
class ReducerComponent[KeyVal[K,V]](f: (V, V) => V) {...}
到我将实例化的时候,ReducerComponent
我所拥有的只是f
and MapOutput
,所以推断 V 是可以的。但是我只有KeyVal[K,V]
一个类的类型参数,它可以不同于KeyVal[_,_]
.
我知道如果您了解类型推断的工作原理,我的要求可能很疯狂,但我不知道!而且我什至不知道什么是继续的好方法——除了在我的高级代码中一直进行显式类型声明。我应该改变所有的架构吗?