Home > OS >  Scala match case with multiple branch with if
Scala match case with multiple branch with if

Time:07-01

I have a match case with if and the expression is always the same. I put some pseudo code:

value match {
  case A => same expression
  case B(_) if condition1 => same expression
  case _ if condition2 => same expression
  ...
  case _ => different expression //similar to an else
}

The match contains both case object (case A) matching and case class(case B(_))

Is it the best practice?

CodePudding user response:

Try to explain this code in words. "This function returns one of two values. The first is returned if the input is A. Or if the input is of type B and a condition holds. Oh, or if a different condition holds. Otherwise, it's the other value". That sounds incredibly complex to me.

I have to recommend breaking this down at least a bit. At minimum, you've got two target expressions, and which one is chosen depends on some predicate of value. That sounds like a Boolean to me. Assuming value is of some trait type Foo (which A.type and B extend), you could write

sealed trait Foo {
  def isFrobnicated: Boolean = this match {
    case A => true
    case B(_) if condition1 => true
    case _ => condition2
  }
}

...

if (value.isFrobnicated) {
  same expression
} else {
  different expression
}

Now the cognitive load is split into two different, smaller chunks of code to digest, and presumably isFrobnicated will be given a self-documenting name and a chunk of comments explaining why this distinction is important. Anyone reading the bottom snippet can simply understand "Oh, there's two options, based on the frobnication status", and if they want more details, there's some lovely prose they can go read in the isFrobnicated docs. And all of the complexity of "A or B if this or anything if that" is thrown into its own function, separate from everything else.

If A and B don't have a common supertype that you control, then you can always write a standalone function, an implicit class, or (if you're in Scala 3) a proper extension method. Take your pick.

Depending on your actual use case, there may be more that can be done, but this should be a start.

CodePudding user response:

It's not common to mix in case objects with case classes in the same pattern match. You should analyze if one could be converted into the other, to have the same thing. Either you match case objects or case classes.

You should not have 2 case _ clauses in a pattern match. If your condition is not dependent on the case clause there is no point in having case _ if condition2 => same expression

You should keep one, and move the if after the arrow symbol :

value match {
  case A => same expression
  case B(_) if condition1 => same expression
  ...
  case _ => 
      if condition2
          same expression
      else 
          different expression //similar to an else
}
  • Related