Syntax for matching multiple cases with guard

I can’t seem to figure out the syntax for the following. I.e., two cases with the same consequent code, but one of the cases has a guard and the other does not.

            dist.get(v) match {
              case Some(d) if alt < d
                | None => {
                dist = dist + (v -> alt)
                pred = pred + (v -> u)
                q.enqueue(v -> alt)
              }
              case _ => ()
            }

Alas, it’s not in the language. You need to repeat the RHS.

It’s a feature I really want, and there has been prior discussion (and I think a draft PR by I think Adriaan). Maybe I’ll try implementing it again. One of the problems in the implementation is that the position of the binding is not singular.

1 Like

What does “single binding position” mean? do you mean the same value needs to be bound multiple times?

I didn’t look properly, and assumed it was the same.

The problem is that the d is available inside the comprehension, and only one alternative binds it. Since you’re not using it inside the comprehension anyway, that could work, but itsn’t implemented.

The more complex scenario (that’s also not supported and I mistook this situation for) is someting like

case (x, y) if x < y | case (y, x) => /* use x and y here, knowing that x <= y */

but yours is simpler still because you don’t need access to d, but equally unsupported.

2 Likes

The alternative ugly way around:

case opt if opt.map(d => alt < d).getOrElse(true) =>
case opt if opt.map(d => alt < d).getOrElse(true) =>

that probably can be rewritten as

case opt if opt.forall(_ > alt) =>
2 Likes