Lawrence Wagerfield
Lawrence Wagerfield

Reputation: 6611

Can I implement a method from a trait using a case statement?

I am trying to implement a method using a case statement, but the following code does not compile.

I am aware I can get this working by using a pattern match, but am curious as to why the case statement is incompatible as a direct implementation....

trait Calculation[Input, Result] {
   def calculate(in: Input): Result
}

class CalculationImpl : Calculation[String, int] {
   // missing parameter type for expanded function
   // The argument types of an anonymous function must be fully known. (SLS 8.5)
   def calculate = {
      case "one" => 1
      case "two" => 2
      case s: String => 0
   }
}

As a compromise, I could change the semantics of the trait so that calculate becomes a parameterless method which returns a Function1, rather than a method which takes an Input parameter and returns a Result. However, this is not ideal...

trait Calculation[Input, Result] {
   def calculate: Input => Result // Works, but semantics have changed.
}

class CalculationImpl : Calculation[String, int] {
   def calculate = {
      case "one" => 1
      case "two" => 2
      case s: String => 0
   }
}

(note: the above is pseudo-code - I have not tried compiling this exact code)

Upvotes: 1

Views: 87

Answers (2)

Aaron Novstrup
Aaron Novstrup

Reputation: 21017

You can get closer to the original semantics and still cut the boilerplate by defining calculate as a function value:

trait Calculation[Input, Result] {
   type F = Input => Result
   val calculate: F
}

class CalculationImpl extends Calculation[String, Int] {
   val calculate: F = {
      case "one" => 1
      case "two" => 2
      case s: String => 0
   }
}

Upvotes: 1

Michał Kosmulski
Michał Kosmulski

Reputation: 10020

You just need to fix your syntax and it will work:

def calculate(s: String) = s match {
  case "one" => 1
  case "two" => 2
  case s: String => 0
}

Upvotes: 4

Related Questions