Search code examples
scalaconstructorcase-class

Scala case class, can't override constructor parameter


I have this case class:

 case class MyCaseClass(left:Long, right: Long = Option[Long], operator: Operator = Option[Operator]){

    def inRange(outer: Long) = outer >= left && outer <= right
  }

This is how I try to instantiate it:

val instance = MyCaseClass(leftValue)

But I get a compilation error:

Unspecified value parameters right, operator

What does this error mean? I just want to have two constructors for a case class: one with three params and one with one param.

This works (as Ende Neu suggested):

case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)

The problem is that I have to wrap right and operator in an Option. The below allows you to avoid Option wrapping for the right and operator parameters (see answer for more details):

object MyCaseClass {
  def apply(left: Long, right: Long, operator: Operator) = new MyCaseClass(left, Option(right), Option(operator))
}

Solution

  • You are not passing a default value, you are passing a type, if you want to pass default parameters you have to specify some value:

    scala>  case class Operator(operation: String)
    defined class Operator
    
    scala>   case class MyCaseClass(left:Long, right: Long = 0L, operator: Operator = Operator("+")){
          |     def inRange(outer: Long) = outer >= left && outer <= right
          |   }
    defined class MyCaseClass
    
    scala>   val instance = MyCaseClass(10L)
    instance: MyCaseClass = MyCaseClass(10,0,Operator(+))
    

    If you want to wrap them in Option you have to declare them so:

     case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)
    

    Where I used None as value, you could use also Some and pass some default value to them.

    If you don't want the user to create a full object using options, create a companion object and define a new apply method:

    case class Operator(operation: String)
    
    object MyCaseClass {
      def apply(left: Long, right: Long, operator: Operator) = new MyCaseClass(left, Option(right), Option(operator))
    }
    
    case class MyCaseClass(left:Long, right: Option[Long] = None, operator: Option[Operator] = None)
    

    You can now construct an object in different ways:

    MycaseClass(10L)
    MycaseClass(10L, Option(10L), Option(Operator("+"))
    MycaseClass(10L, 20L, Operator("+"))