Abdul Rahman
Abdul Rahman

Reputation: 1384

Context Bounds and Classes

What is wrong with the following function definition.

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

I get can not resolve symbol <. Since Ordered is a context class of A shouldnt it be able to resolve < ? What am I missing?

Upvotes: 3

Views: 452

Answers (2)

cchantep
cchantep

Reputation: 9168

Ordered is not a typeclass, but a base trait for plain inheritance.

So either you update to ...

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

... or you use the Ordering typeclass keeping the context bounds:

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)

Personally I don't recommend the implicit conversion from import scala.math.Ordering.Implicits._ (auto-magic stuff).

Upvotes: 5

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149636

Ordered[T] is a trait which extends the Comparable[T] interface in Java. You implement it on a class where you want to compare the current instance of your class with another instance of that same class. What you're actually looking for is to use Ordering[T] which extends Comparator[T] in Java. It takes two elements and tells you if one is less than\equal to\larger than the other. As you're using Context Bounds, you can access the Ordering[T] via implicitly

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

As @m-z said, you can also import scala.math.Ordering.Implicits._ to use the < method:

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

Upvotes: 2

Related Questions