Jianfeng Jianfeng - 3 months ago 11
Scala Question

How to combine the same function for different types of argument in 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?

Answer

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