Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default generic type on method in scala

Tags:

generics

scala

I'm trying to figure out a way to get away from overloaded methods. Currently I'm using this approach to provide nice APIs to the user:

  def get(id: String): Option[JsonDocument]

  def get(id: String, timeout: Duration): Option[JsonDocument]

  def get[D <: Document[_]](id: String, target: Class[D]): Option[D]

  def get[D <: Document[_]](id: String, target: Class[D], timeout: Duration): Option[D]

Now since scala has default parameters I want to condense this into one method. But because D is generic, I need the default if not provided not to be "Nothing", but rather "JsonDocument".

My current approach does this:

  def get[D <: Document[_]](id: String, target: Class[D] = classOf[JsonDocument], timeout: Duration = null): Option[D]

And as it turns out the compiler is super happy with it, but the IDE has problems. if the target is not explicitly provided (like with target = JsonDocument or any other) it thinks the return type is Option[Nothing] and therefore its confusing to the user.

So my question is: with these types, is it possible to provide a "default" type of JsonDocument for type D if it is not provided by the user to be overridden?

like image 448
daschl Avatar asked Jan 26 '26 01:01

daschl


1 Answers

There is an solution to the default generic parameters problem given at http://www.cakesolutions.net/teamblogs/default-type-parameters-with-implicits-in-scala. Applying to your case, you'd get something like (untested):

trait DefaultsTo[Type, Default]

object DefaultsTo {
  implicit def defaultDefaultsTo[T]: DefaultsTo[T, T] = null
  implicit def fallback[T, D]: DefaultsTo[T, D] = null  
}

// use target.runtimeClass in the implementation
def get[D <: Document[_]](id: String, timeout: Duration)(implicit target: scala.reflect.ClassTag[D], default: DefaultsTo[D, JsonDocument]): Option[D]

To use: get(id, timeout) for JsonDocument or get[OtherDocument](id, timeout). Of course, whether the IDE (IntelliJ?) is going to infer the type correctly is a different question!

like image 167
Alexey Romanov Avatar answered Jan 29 '26 18:01

Alexey Romanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!