Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine the same function for different types of argument in scala

Tags:

scala

E.g., I had two exactly the same lessThan function for JsNumber and JsString.

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
  }
}

These two functions are exactly the same but the input argument types. JsNumber and JsString are from the library play-json that extend from the JsValue. However, the value and < is not part of the super's traits. Any good ideas to combine these to one general function?

like image 334
Jianfeng Avatar asked Jan 24 '26 06:01

Jianfeng


1 Answers

You need to provide some proof that both types support ordering. You can do this with the Ordering typeclass:

// 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
  }
}
like image 183
Alvaro Carrasco Avatar answered Jan 26 '26 20:01

Alvaro Carrasco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!