Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit parameter and ClassTag

Can someone explain what the Scala compiler is trying to tell me with the error message below?

object Some {
  def apply[T: ClassTag](data: T)(implicit ordering: Ordering[T]): T = data
}
object Other {
  def apply[T: ClassTag](data: T)(implicit ordering: Ordering[T]): T =
    Some(data)(ordering.reverse)
}

Compiler says:

not enough arguments for method apply: (implicit evidence$2: scala.reflect.ClassTag[T], implicit ordering: Ordering[T])T in object Some. Unspecified value parameter ordering.

The error arose when I added the ClassTag to the method in object Some, in order to use some internal arrays there. Initially, the code was (and compiled without errors):

object Some {
  def apply[T](data: T)(implicit ordering: Ordering[T]): T = data
}
object Other {
  def apply[T: ClassTag](data: T)(implicit ordering: Ordering[T]): T =
    Some(data)(ordering.reverse)
}

I know ClassTag adds an implicit with type information to overcome erasure, but I don't understand what that has to do with my ordering implicit parameters, or why the compiler suddenly thinks that ordering has no value...

like image 977
Alexandros Avatar asked Dec 25 '22 09:12

Alexandros


1 Answers

This:

def apply[T: ClassTag](data: T)(implicit ordering: Ordering[T]): T = data

is syntactic sugar for this:

def apply[T](data: T)(implicit evidence: ClassTag[T], ordering: Ordering[T]): T = data

When you explicitly specify the implicit parameters you must provide both of them. You can use implicitly to carry over the implicit ClassTag:

object Other { 
  def apply[T: ClassTag](data: T)(implicit ordering: Ordering[T]): T =
    Some(data)(implicitly, ordering.reverse)
}
like image 143
wingedsubmariner Avatar answered Jan 13 '23 11:01

wingedsubmariner