Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method to return first of two values

Tags:

generics

scala

I need a method to return the first of two ordered values. I've tried:

def first[T <: Ordered[T]](a: T, b: T) = {
  a compare b match {
    case -1 | 0 => a
    case 1      => b
  }
}

but get

scala> first(3,4)
<console>:9: error: inferred type arguments [Int] do not conform to method first's 
type parameter bounds [T <: Ordered[T]]
       first(3,4)
       ^

I guess this is because Int needs to be converted to a RichInt, which is an Ordered[Int] rather than an Ordered[RichInt]. What next?

like image 586
Luigi Plinge Avatar asked Aug 14 '11 15:08

Luigi Plinge


People also ask

How do I return a generic response in Java?

(Yes, this is legal code; see Java Generics: Generic type defined as return type only.) The return type will be inferred from the caller. However, note the @SuppressWarnings annotation: that tells you that this code isn't typesafe. You have to verify it yourself, or you could get ClassCastExceptions at runtime.

Which of these parameters is used for a generic class to return and accept any type of object?

Which of these type parameters is used for a generic class to return and accept any type of object? Explanation: T is used for type, A type variable can be any non-primitive type you specify: any class type, any interface type, any array type, or even another type variable. 3.


1 Answers

You can use type class Ordering and context bound:

def first[T : Ordering](a: T, b: T) = {
  implicitly[Ordering[T]].compare(a, b) match {
    case -1 | 0 => a
    case 1      => b
  }
}

Update

This code can be simplified further if you import scala.math.Ordered._. Companion object of Ordered has orderingToOrdered implicit conversion, so everything that has Ordering would also be treated as Ordered:

import scala.math.Ordered._

def first[T : Ordering](a: T, b: T) = if (a <= b) a else b
like image 104
tenshi Avatar answered Oct 20 '22 07:10

tenshi