简体   繁体   中英

How to minimally reconcile Scala's @specialized and java.lang.Comparable?

I have a third party Java API with methods like this (simplified) :

public <C extends Comparable<C>> C jFoo(C c);

I want to write a wrapper like this:

def foo[C <: Comparable[C]](c: C): C = jFoo(c)

For allowing the wrapper method to accept primitives (since, to my understanding, boxing will happen anyway so that's not relevant), I want to specialize C :

def foo[@specialized(Int, Double) C <: Comparable[C]](c: C): C = jFoo(c)

However, scalac complains that, due to the upper bound on the parameter, the method cannot be specialized.

A solution would be to add an evidence parameter:

def foo[@specialized(Int, Double) C, CC <: Comparable[CC]](c: C)
                                                 (implicit evComp: C => CC): CC =
    jFoo(evComp(c))

This works, and you can now call:

foo(2.0)

However, the method signature - part of the API - is not really readable now.

Is there an alternative approach at the method level that would produce an equivalent, more readable signature, while maintaining specialization?

(Scala 2.12.x is fine, Dotty not so much)

You could get rid of the second type parameter CC by making it a type member of a special EvC type class.

The following works:

import java.lang.Comparable

def jFoo[C <: Comparable[C]](c: C): Unit = println("compiles => ship it")

trait EvC[C] {
  type CC <: Comparable[CC]
  def apply(c: C): CC
}

def foo[@specialized(Int, Double) C](c: C)(implicit evC: EvC[C]): Unit = 
  jFoo[evC.CC](evC(c))

implicit object DoubleEvC extends EvC[Double] {
  type CC = java.lang.Double
  def apply(c: Double) = (c: java.lang.Double)
}

foo(42.0) // compiles => ship it

In a sense, I've just glued together the C => CC part with the type argument CC itself, so that the type CC does no longer appear in the type parameter list. I'm not sure whether you can get rid of all of that completely, it's still a fact that the built-in primitive types do not implement java.lang.Comparable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM