2011-02-02 25 views
4

this questionで作業しているうちに、次の問題が発生しました。コレクションは要素型に対して暗黙的な変換をどのように使用できますか?

def foo[T <: Ordered[T]](s : Seq[T]) = s.sorted 

def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 

最初のコンパイルは2番目のコンパイルではありません。コンパイラは、アサートされた暗黙の変換を使用してOrderingを取得できることを理解していません。我々は少しを助けている場合、それは動作します:匿名関数をコンパイルするコンパイラがメソッド<=を見つけるための暗黙的な変換が適用されるが

def foo[T <% Ordered[T]](s : Seq[T]) = s.sortWith(_<=_) 

、すべてが正常です。

私は別の例はありませんが、要素が特定のプロパティを持つことを必要とするコレクション上の他の関数で同様の問題が起きると考えられます(変換によってのみアサートできる場合)。

コンパイラがこのように制限されている特別な理由はありますか?このような問題を解決する一般的な方法はありませんか? (ここでは簡単です)回避策はありますか? Key[T]のプロパティをTに変換する別の暗黙の変換?

(最後の考えは、Tの具体的な値がプロパティを持つことになり、あいまいな状況になる場合は問題があることに注意してください)。

答えて

4
scala> implicit def ordering[T <% Ordered[T]] = new Ordering[T]{def compare(x: T, y: T) = x compare y} 
ordering: [T](implicit evidence$1: (T) => Ordered[T])java.lang.Object with Ordering[T] 

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T] 
+0

2.8.1-finalのための有効なソリューションです。ありがとうございます。私は、シナリオごとに特別な要素プロパティ(ここでは 'Ordering')を記述する特殊な型を持たなければならないとすれば、一般的な方法はないと思いますか? – Raphael

+0

このように定義された順序付けは 'T <:Ordered [T]'の場合でも使用されることに注意してください。明らかに、暗示は静的に解決されます。 – Raphael

3
% scala29 
Welcome to Scala version 2.9.0.r24168-b20110202012927 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted 
foo: [T](s: Seq[T])(implicit evidence$1: (T) => Ordered[T])Seq[T] 

scala> 

ところで、 "ここでは簡単に思える" 再、そうではありませんでした。このようなインプリチットは発散的で、彼らはかなり決定されています。

+0

それは2.9で解決されるので、クールです。あなたが1つか2つの重要な議論をしてください、それは簡単ではないでしょうか?もしも 'T <:Ordered [T]'、 '' compare''が暗黙的に到達可能であればどうなりますか? – Raphael

+0

説明が簡単ではありません。基本的にサイクルは発展し、それらを解明するのは非常に面倒です。図書館には多くの競合する懸念事項があります。小さな変化は(ある例として)人々がそれが変わるのを見たくないいくつかの関数の型推論行動に影響を与えることができます。等。 – extempore

関連する問題