2016-08-25 96 views
3

例如,對於JsNumberJsString,我有兩個完全相同的函數lessThan如何在scala中爲不同類型的參數組合相同的函數

def ltNum(left: JsNumber, right: JsNumber, order: SortOrder.Value): Boolean = { 
    if (left.value < right.value) { 
    order == SortOrder.ASC 
    } else { 
    order == SortOrder.DSC 
    } 
} 

def ltStr(left: JsString, right: JsString, order: SortOrder.Value): Boolean = { 
    if (left.value < right.value) { 
    order == SortOrder.ASC 
    } else { 
    order == SortOrder.DSC 
    } 
} 

這兩個函數是完全相同的,但輸入參數類型。 JsNumberJsString來自從JsValue延伸的庫play-json。但是,value<不是超級特性的一部分。任何將這些結合到一個一般功能的好主意?

回答

5

您需要提供一些證明,表明兩種類型都支持排序。你可以用Ordering類型來做到這一點:

// you'll have to figure out a good place to put these 
// they'll need to be in scope whenever you *call* the `lt` method 
implicit val jsNumberOrdering: Ordering[JsNumber] = Ordering.by(_.value) 
implicit val jsStringOrdering: Ordering[JsString] = Ordering.by(_.value) 

def lt [A <: JsValue : Ordering] (left: A, right: A, order: SortOrder.Value): Boolean = { 
    import Ordering.Implicits._ // will give you the `<` method 
    if (left < right) { 
    order == SortOrder.ASC 
    } else { 
    order == SortOrder.DSC 
    } 
} 
+0

op還需要實際爲這兩個實現排序並將其放在範圍內。 –

+0

@Łukasz嗯...出於某種原因,我認爲已經存在... ...好趕上。更新。 –

+0

我不確定它是否存在,但即使它不存在,也值得一提,因爲問題的答案實際上是:「使用類型類」,並且它將更容易理解OP正在進行的操作; p –

0

這是仿製藥進來你應該能夠定義諸如

def lt[T](left: T, right: T, order: SortOrder.Value): Boolean 

在你的情況的東西,你也可能要添加綁定如果需要的話 -

def lt[T <: JsValue](left: T, right: T, order: SortOrder.Value): Boolean 

http://docs.scala-lang.org/tutorials/tour/upper-type-bounds.html

+0

通常也稱爲'類型參數化'在斯卡拉。 –

+0

看不出有什麼幫助,'T'沒有'<'方法 –

相關問題