2011-01-13 31 views
7

DateTime(joda)で> =、>などを使用しようとしています。変換DateTimeから暗黙的に暗黙的に暗黙的に暗黙的に暗黙的に暗黙的に暗黙的に暗黙変換に変換することができません

implicit def dateTime2ordered(x: DateTime): Ordered[DateTime] = 
new Ordered[DateTime] with Proxy { 
    val self = x 

    def compare(y: DateTime): Int = { 
    x.compareTo(y) 
    } 
} 
私は

implicit def comparable2ordered[A <: Comparable[A]](x: A): Ordered[A] = 
    new Ordered[A] with Proxy { 
     val self = x 

     def compare(y: A): Int = { 
     x.compareTo(y) 
     } 
    } 

ような、より一般的な形式を好むだろう。しかし、コンパイラは、この変換を見つけることができない、そしてそれを直接起動しようとした後、私は次のメッセージを得ている

DateTimeの型がComparable [A]ではないと主張します。 DateTimeのソースを調べた後、私はそれが生の型としてComparableだけを実装しているのを見ました。

は私が

implicit def comparable2ordered[A <: Comparable[_]](x: A): Ordered[A] = 
    new Ordered[A] with Proxy { 
     val self = x 

     def compare(y: A): Int = { 
     x.compareTo(y) 
     } 
    } 

を使用して、それが仕事を得ることができた私の質問は:これは、この問題の正しいScalaの治療法である、またはワイルドカード型は型チェックと将来の問題原因バインドでしょうか?

答えて

2

参照してください、事は、これは既に存在します。あなたが暗黙の変換が探しているオブジェクトOrdered、内部を見る場合はまあ、一種の...、あなたはこれを見つけることができます:

implicit def orderingToOrdered [T] (x: T)(implicit ord: Ordering[T]) : Ordered[T] 

だから、限り利用可能Ordering[T]ありますように、1はOrdered[T]を生成することができます。さて、Orderingオブジェクトの内部Ordering[T]を探すために:

implicit def ordered [A] (implicit arg0: (A) ⇒ Comparable[A]) : Ordering[A] 

をので、あなたはOrdered[A]を期待して何かにcomparable: A with Comparable[A]を渡した場合、それがこれを行います。

Ordered.orderingToOrdered(comparable)(Ordering.ordered(Predef.identity(comparable))) 

を今、あなたの質問にとして:存在する型の使用はJavaの生の型を扱う正しい方法です。理論的にはこれによって誤った順序付けが行われる可能性がありますが、実際にはほとんど起こりそうにありません。 は暗黙のあいまいさに問題がありますが、上記のようにScalaに既にComparable => Orderedの暗黙の変換があるためです。

6

私も、関係演算子を使ってjoda DateTimeオブジェクトを比較しようとしていたので、私はこの質問に遭遇しました。

ダニエルの答えが正しい方向に私を指摘:scala.math.Orderedに存在する暗黙のはOrdered[A]A extends java.lang.Comparable[A]のインスタンスに変換します - 彼らはちょうど範囲に持ち込まする必要があります。(私はところで、hereを学んだ)これを行う最も簡単な方法は、implicitly方法である:キャッチorg.joda.time.DateTimeComparable自体を拡張したり実装していないということです

val aOrdering = implicitly[Ordering[A]] 
import aOrdering._ 

、それはorg.joda.time.ReadableInstantから(間接的に)継承し、そのComparableに拡張されます。だから、これは:DateTimeComparable[DateTime]を拡張していないため

val dateTimeOrdering = implicitly[Ordering[DateTime]] 
import dateTimeOrdering._ 

、コンパイルされません。 DateTimeOrderedの関係演算子を使用するには、代わりにこれをしなければならない:ReadableInstantComparable[ReadableInstant]を拡張し、Orderedにおける暗黙の変換がOrdered[ReadableInstant]に変換することができますので、作品

val instantOrdering = implicitly[Ordering[ReadableInstant]] 
import instantOrdering._ 

これまでのところ、とても良いです。しかし、Ordered[ReadableInstant]が十分でない状況があります。 (私が遭遇した一つはScalaTestのgreater and less than Matchersである。)Ordered[DateTime]を取得するには、私はこれを行うことを余儀なくされた。

implicit object DateTimeOrdering extends Ordering[DateTime] { 
    def compare(d1: DateTime, d2: DateTime) = d1.compareTo(d2) 
} 

それはそこには、簡単な方法であるべきように思えるが、私は1アウトを把握できませんでした。

+0

私はこれがうまくいくと思います: 'import com.github.nscala_time.time.Imports._' – Chris

+0

これはうまく動作しますが、nscala-timeライブラリを使用している場合のみです。 ;) –

+0

私は「拡張オーダー」ソリューションが好きです:短くて清潔で、「魔法」を最小限に保ちます – Integrator

関連する問題