-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Motivation
I often come across a situation where I need to match on some outer pattern and then match on some attribute of the value exposed by that pattern. If the second match is not exhaustive it means I need the same fall back clause for the inner as well as the outer match, which is annoying. Consider for example the following class hierarchy:
sealed class T:
def underlying: T = ...
class A extends T
class B extends T
class C extends TI want to match on T's that have an underlying A or B and return a fallback for the rest. In current Scala, here's what I need to do:
x match
case x: T =>
x.underlying match
case x: A => ...
case x: B => ...
case _ => fallback
case _ => fallbackThe duplication of fallback is annoying, in particular if fallback is naturally a list of cases by itself.
The proposal here is to introduce the following shorthand:
x match
case x: T if x.underlying match
case x: A => ...
case x: B => ...
case _ => fallbackSyntax:
CaseClause ::= `case` Pattern [Guard] `=>` Block
| `case` Pattern `if` InfixExpr MatchClause
| `case` Pattern `if` [InfixExpr `&&`] SimpleExpr `.` MatchClause
Informal Specification:
A pattern guard may end in a match expression, which in this case replaces the pattern's right hand side.
If some clause of the second match expression matches, its right hand side defines the result of the match as a whole. If no clause in the second match expression matches, the next clause of the outer match is tried.
Related proposals
- Pattern guards in Haskell: https://wiki.haskell.org/Pattern_guard
- Destructuring pattern guards in https://lptk.github.io/programming/2018/12/12/scala-pattern-warts-improvements.html.
Both of these allow a single destructuring in a guard, whereas the proposal here allows multiple destructings. IMO either approach would be an improvement on what we have.