Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default value for type parameter in Scala

Tags:

generics

scala

I'm failing to figure out how (if at all) you can set a default value for a type-parameter in Scala.
Currently I have a method similar to this:

def getStage[T <: Stage](key: String): T = {
  // Do fancy stuff that returns something
}

But what I'd like to do is provide an implementation of getStage that takes no value for T and uses a default value instead. I tried to just define another method and overload the parameters, but it only leads to one of the methods being completely overriden by the other one. If I have not been clear what I'm trying to do is something like this:

def getStage[T<:Stage = Stage[_]](key: String): T = {

}

I hope it's clear what I'm asking for. Does anyone know how something like this could be achieved?

like image 394
evotopid Avatar asked Apr 02 '15 13:04

evotopid


People also ask

What is type parameter in Scala?

Language. Methods in Scala can be parameterized by type as well as value. The syntax is similar to that of generic classes. Type parameters are enclosed in square brackets, while value parameters are enclosed in parentheses.

What is the function parameter with a default value in Scala?

Scala provides the ability to give parameters default values that can be used to allow a caller to omit those parameters. The parameter level has a default value so it is optional. On the last line, the argument "WARNING" overrides the default argument "INFO" .

What is a default parameter value?

In JavaScript, a parameter has a default value of undefined. It means that if you don't pass the arguments into the function, its parameters will have the default values of undefined .

What is the default value for string in Scala?

def aMethod(param: String = "asdf") = { ... } If the method is called as follows, then param is given the default value "asdf": aMethod() ...


1 Answers

You can do this kind of thing in a type-safe way using type classes. For example, suppose you've got this type class:

trait Default[A] { def apply(): A } 

And the following type hierarchy:

trait Stage case class FooStage(foo: String) extends Stage case class BarStage(bar: Int) extends Stage 

And some instances:

trait LowPriorityStageInstances {   implicit object barStageDefault extends Default[BarStage] {     def apply() = BarStage(13)   } }  object Stage extends LowPriorityStageInstances {   implicit object stageDefault extends Default[Stage] {     def apply() = FooStage("foo")   } } 

Then you can write your method like this:

def getStage[T <: Stage: Default](key: String): T =   implicitly[Default[T]].apply() 

And it works like this:

scala> getStage("") res0: Stage = FooStage(foo)  scala> getStage[BarStage]("") res1: BarStage = BarStage(13) 

Which I think is more or less what you want.

like image 161
Travis Brown Avatar answered Sep 30 '22 13:09

Travis Brown