2016-04-13 15 views
3

次の関数定義で何が問題になりますか。コンテキスト境界とクラス

def f[A: Ordered] (a: A, b: A): Boolean = a < b 

シンボル<を解決できません。 OrderedはAのコンテキストクラスであるため、<を解決することはできませんか?私は何が欠けていますか?

+0

私の場合、「Ordered」はtypeclassではなく、プレーンな継承のための基本特性です。したがって、あなたは 'def [A <:Ordered [_]](a:A、b:A):Boolean = a cchantep

+0

@cchantepこれはコメントではなく、答えでなければなりません。 –

+0

スカラーは型パラメータとして私たちが持っているものを実際にチェックしていませんか? typeclassまたは形質ですか? – Pavel

答えて

2

Ordered[T]は、JavaでComparable[T]インターフェイスを拡張する特性です。クラスの現在のインスタンスと同じクラスの別のインスタンスを比較するクラスに実装します。あなたが実際に探しているのは、JavaでComparator[T]を拡張しているOrdering[T]を使用することです。それは2つの要素を取り、1つが\と他のものよりも大きいかどうかをあなたに伝えます。 、

import scala.math.Ordering.Implicits._ 
def f[A: Ordering](a: A, b: A): Boolean = a < b 
+0

'a

+0

@ m-z追加!ありがとうございました。 –

+0

ええ、私はこれを不必要に複雑にしています。どうして彼らはそれをやっているのですか?haskellは型クラスでそれをどうやって行うのですか?暗黙的に[Ordering [A]]。lt(a、b)とimport scala.math.Ordering.Implicits._は、不必要に複雑に見えるだけです。 –

3

Orderedは型クラスではありません:あなたはコンテキスト境界を使用しているとして、あなたは@mzが言ったように、あなたもimport scala.math.Ordering.Implicits._<メソッドを使用することができますimplicitly

def f[A: Ordering](a: A, b: A): Boolean = implicitly[Ordering[A]].lt(a, b) 

経由Ordering[T]にアクセスすることができます明白な継承のための基本形質です。

ですから...

def f[A <: Ordered[_]](a: A, b: A): Boolean = a < b 

に更新する...か、コンテキスト境界を維持型クラスOrderingを使用するか:

個人的に
def f[T : Ordering](a: T, b: T): Boolean = { 
    val order = implicitly[Ordering[T]] 
    order.lt(a, b) 
} 

// Or: 
def f[T](a: T, b: T)(implicit order: Ordering[T]): Boolean = order.lt(a, b) 

私は暗黙のはお勧めしません。 import scala.math.Ordering.Implicits._(自動魔法のもの)からの変換。