Blankman
Blankman

Reputation: 267040

Upgraded to scala 2.11 from 2.9: Type argument Any does not conform to type parameter bounds T <: Comparable

I understand what the error message is saying, but not sure where exactly I need to add some sort of type bounds.

Do java integer values not inherit from Comparable? Not sure if I am focused on the correct area here.

type arguments [Any] do not conform to method comp's type parameter bounds [T <: Comparable[T]] [error] inclusive(java.lang.Integer.valueOf(start), java.lang.Integer.valueOf(finish), succ, comp).map(_.toInt)

def inclusive[T <: Comparable[T]](
    start: T,
    finish: T,
    succ: (T) => T,
    comp: (T, T) => Int
): Seq[T] = {
  val ret = new ArrayBuffer[T]
  var value: T = start
  while (comp(value, finish) <= 0) {
    ret += value
    value = succ(value)
  }
  ret.toSeq
}

private def comp[T <: Comparable[T]](a: T, b: T) = {
  if (a != null)
    a.compareTo(b)
  else if (b == null) 0
  else -1
}

private def compInt(a: Int, b: Int) = {
  a - b
}

def inclusive[T <: Comparable[T]](
    start: T,
    finish: T,
    succ: (T) => T
): Seq[T] = {
  inclusive(start, finish, succ, comp[T])
}

def inclusive(start: util.Date, finish: util.Date): Seq[util.Date] = {
  inclusive(start, finish, succDate, comp[Date])
}

def inclusive(start: String, finish: String): Seq[String] = {
  inclusive(start, finish, succString, comp[String])
}

private def succ(x: java.lang.Integer): java.lang.Integer = x + 1
private def comp(
    x: java.lang.Integer,
    y: java.lang.Integer
): java.lang.Integer = x - y

def inclusive(start: Int, finish: Int): Seq[Int] = {
  inclusive(
    java.lang.Integer.valueOf(start),
    java.lang.Integer.valueOf(finish),
    succ,
    comp
  ).map(_.toInt)
}

Upvotes: 0

Views: 68

Answers (1)

user
user

Reputation: 7604

This is because your comp parameter is a function that returns an Int instead of a java.lang.Integer like your other methods. The problem becomes clear when you add an explicit type parameter:

inclusive[java.lang.Integer](
    java.lang.Integer.valueOf(start),
    java.lang.Integer.valueOf(finish),
    succ _,
    comp _
  )

Error:

overloaded method inclusive with alternatives:
  (start: Integer,finish: Integer,succ: Integer => Integer)Seq[Integer] 
  (start: Integer,finish: Integer,succ: Integer => Integer,comp: (Integer, Integer) => Int)Seq[Integer]
 cannot be applied to (Integer, Integer, Integer => Integer, (Integer, Integer) => Integer)

Instead of the version of the comp that returns an Int

def comp[T <: Comparable[T]](a: T, b: T) //: Int (inferred)

it chooses the version of comp with this signature, which returns a java.lang.Integer, causing a type mismatch:

def comp(x: java.lang.Integer, y: java.lang.Integer): java.lang.Integer

You can fix this by adding type parameters in your call to comp to get the version that returns an Int:

def inclusive(start: Int, finish: Int): Seq[Int] = {
  inclusive(
    java.lang.Integer.valueOf(start),
    java.lang.Integer.valueOf(finish),
    succ _,
    comp[java.lang.Integer] _
  ).map(_.toInt)
}

or change the signature of your first inclusive function to this:

def inclusive[T <: Comparable[T]](
    start: T,
    finish: T,
    succ: (T) => T,
    comp: (T, T) => java.lang.Integer <- Used to be Int
): Seq[T]

You might be able to turn all of that into just this though:

import scala.math.Ordering.Implicits._

def inclusive[T](
    start: T,
    finish: T,
    succ: (T) => T
)(implicit ord: Ordering[T]): Seq[T] =
  LazyList.iterate(start)(succ).takeWhile(_ < finish)

def inclusive(start: Int, finish: Int): Seq[Int] = {
  inclusive[Int](start, finish, (_ + 1))
}

Upvotes: 3

Related Questions