2016-08-25 2 views
3

たとえば、JsNumberJsStringの場合は全く同じlessThan関数を使用しました。スカラーでさまざまなタイプの引数に同じ関数を組み合わせる方法

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

これらの2つの機能はまったく同じですが、入力引数の種類は同じです。 JsNumberおよびJsStringは、JsValueから延在するライブラリplay-jsonからのものである。しかし、value<はスーパーの特性の一部ではありません。 1つの一般的な機能にこれらを組み合わせるための良いアイデアですか?

答えて

5

両方のタイプが注文をサポートするという証拠を提供する必要があります。 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 
    } 
} 
+0

opは実際にそれらの2つのために順序付けを実装し、スコープに入れる必要がある。 –

+0

@Łukaszうーん...何らかの理由で私はすでに存在していると思った。更新しました。 –

+0

私はそれが存在するかどうかはわかりませんが、たとえそれが言及されていなくても、質問への答えは実際には:「タイプ・クラスを使用する」ことで、OPのために何が起こっているのかを理解するのがより簡単になります。 –

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

Scalaでは「タイプパラメータ化」とも呼ばれます。 –

+0

それがどのように役立つか分からない、 'T'は' <'メソッドを持たない。 –

関連する問題