我想寫一個通用的加權平均函數。 我想放寬對相同類型的值和權重的要求。即,我想支持說的序列:(value:Float,weight:Int)
和(value:Int,weight:Float)
參數,並不僅僅是:(value:Int,weight:Int)
Scala:通用函數乘法不同類型的數字編號
要做到這一點,我首先需要實現的功能,它有兩個通用的數值,並返回他們的產品。
def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : ??? = {...}
書寫簽名,並想返回類型,讓我意識到我需要定義某種層次的數值運算到確定返回類型。即x:Float*y:Int=z:Float
,x:Float*y:Double=z:Double
。
現在,Numeric類僅爲相同類型的參數定義操作plus
,times
等。我想我會需要實現一個類型:
class NumericConverter[Numeirc[A],Numeric[B]]{
type BiggerType=???
}
,這樣我可以寫我的時間功能:
def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) :
NumericConverter[Numeirc[A],Numeric[B]].BiggerType= {...}
和「較小型」轉換爲「大」,並給它到times()
。
我在正確的軌道上嗎?我將如何「實施」BiggerType
?作爲動態評估,因此worn't工作
type myType = if(...) Int else Float
:
清楚,我不能這樣做。
我知道我可以這樣做使用Scalaz等,但這是一個學術練習,我想了解如何編寫一個基於參數類型靜態返回類型的函數。
隨時讓我知道是否有一個更簡單的方法來做到這一點。
更新:
這是我想出了它。
abstract class NumericsConvert[A: Numeric,B: Numeric]{
def AisBiggerThanB: Boolean
def timesA=new PartialFunction[(A,B), A] {
override def isDefinedAt(x: (A, B)): Boolean = AisBiggerThanB
override def apply(x: (A, B)): A = implicitly[Numeric[A]].times(x._1, x._2.asInstanceOf[A])
}
def timesB=new PartialFunction[(A,B), B] {
override def isDefinedAt(x: (A, B)): Boolean = !AisBiggerThanB
override def apply(x: (A, B)): B = implicitly[Numeric[B]].times(x._1.asInstanceOf[B], x._2)
}
def times: PartialFunction[(A, B), Any] = timesA orElse timesB
}
def times[A: Numeric, B: Numeric](x: B, y: A)= implicitly[NumericsConvert[A,B]].times(x,y)
這是愚蠢的,因爲我將要創建兩個
IntDouble extends NumericsConvert[Int,Double]
和
DoubleInt extends NumericsConvert[Double,Int]
不implicits提及的times
返回類型現在是Any
,但無論如何,我的時代功能出現錯誤。我想我會在這裏添加它,以免它可能有助於達成解決方案。所以旁邊的問題:我怎麼可以將一個類/函數的上下文綁定類型傳遞給另一個像我試圖在時間。
呃!演員陣容完成了! :D – ShS
隨時在您的答案中添加對http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-conversions的引用,以解釋在幕後發生的事情。 – ShS
好吧,所以我讓我的方法工作,但它有一個小問題。看看你是否可以幫助我解決它:http://stackoverflow.com/questions/43382282/scala-generic-weighted-average-function – ShS