抽象了路径依赖型比方说,我有一个类:斯卡拉:在impilicit参数
abstract class NumericCombine[A:Numeric,B:Numeric]{
type AB <: AnyVal
}
我想定义返回NumericCombine[A,B].AB
类型的值的函数。例如:
def plus[A: Numeric,B:Numeric](x: A, y: B): NumericCombine[A,B].AB
但编译器不让我参考.AB
加号。
FYI,this是这个问题的背景。
我想提供:
implicit object IntFloat extends NumericCombine[Int,Float]{override type AB = Float}
implicit object FloatInt extends NumericCombine[Float,Int]{override type AB = Float}
和其他44个朋友(7 * 6-2),这样我可以如下定义我plus
:
def plus[A: Numeric,B:Numeric](x: A, y: B): NumericCombine[A,B].AB =
{
type AB = Numeric[NumericCombine[A,B].AB]
implicitly[AB].plus(x.asInstanceOf[AB],y.asInstanceOf[AB])
}
plus(1f,2)//=3f
plus(1,2f)//=3f
我知道的事实上,在斯卡拉值转换允许我定义
def plus[T](a: T, b: T)(implicit ev:Numeric[T]): T = ev.plus(a,b)
并实现上述行为作为建议但由于我想将此函数用作较大函数的一部分(在作为此问题的上下文中所述的链接中进行了描述),因此我需要使用A
和B
对函数进行参数化。
更新:
我做了一些这方面的良好进展。
我NumericCombine
现在看起来是这样的:
abstract class NumericCombine[A: Numeric, B: Numeric] {
type AB <: AnyVal
def fromA(x: A): AB
def fromB(y: B): AB
val numeric: Numeric[AB]
def plus(x: A, y: B): AB = numeric.plus(fromA(x), fromB(y))
def minus(x: A, y: B): AB = numeric.minus(fromA(x), fromB(y))
def times(x: A, y: B): AB = numeric.times(fromA(x), fromB(y))
}
和我加的功能是这样的:
def plus[A: Numeric, B: Numeric](x: A, y: B)(implicit ev:NumericCombine[A,B])
: ev.AB = ev.plus(x, y)
需要plus
加权平均函数最终成为一个比较复杂一点:
def accumulateWeightedValue[A: Numeric,B: Numeric]
(accum: (A, NumericCombine[A, B]#AB), ValueWithWeight: (A, B))
(implicit combine: NumericCombine[A, B], timesNumeric: Numeric[NumericCombine[A, B]#AB])
:(A,NumericCombine[A, B]#AB)=
这是一个函数,需要(A,AB),(A,B)
并返回(A,AB)
。我在内部使用它里面weightedSum
刚刚聚集在此:
def weightedSum[A: Numeric,B: Numeric](weightedValues: GenTraversable[(A, B)])
(implicit numericCombine: NumericCombine[A, B], plusNumeric: Numeric[NumericCombine[A, B]#AB])
: (A, NumericCombine[A, B]#AB)
现在,这个编译罚款。它似乎对第二个隐式参数有问题。即数字[AB]当我运行与隐含的价值为NumericCombine[Int,Float]
目前。它给我:
找不到参数plusNumeric隐含值: 数字[NumericCombine [整型,浮点] #AB]
注意,在NumericCombine,我有一个数字[AB]其中应该可用于隐式查找。在本地存储,在[Int,Float]
情况:
val lst: Seq[(Int, Float)] =List((1,3f),(1,4f))
implicit val num: Numeric[Float] = IntFloat.numeric //IntFloat extends NumericCombine[Int,Float]
weightedSum(lst)
在一个局部变量
调用函数需要它之前似乎并没有产生任何影响。那么为什么它会被隐式系统拾取。
的'NumericCombine [A,B]#AB'觉得作为'NumericCombine的所有实例的常见类型'AB' [A,B]'可以存在。所以'accum'的类型是错误的。 –
我明白了。那么有没有什么方法可以抽象出这些AB?允许其他函数使用这个通用加号? – ShS
你说'accumulateWeightedValue'被用在'weightedSum'里面。所以,只要将它设为本地方法,就可以使用'numericCombine.AB'。 “A”和“B”不应该需要'加数字'或'数字'约束。 –