抽象了路徑依賴型比方說,我有一個類:斯卡拉:在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」不應該需要'加數字'或'數字'約束。 –