Nest patterns in guards #17728
Replies: 4 comments
-
I love it! This would be even more useful than the one I proposed in the blog post. |
Beta Was this translation helpful? Give feedback.
-
I think the syntax here is actually very surprising? This compiles right now: case class Foo(underlying: Int)
Foo(1) match {
case x if x.underlying match {
case 1 => true
case _ => false
} => "true"
case _ => "false"
} Am I right that you need to look fairly far ahead to see that there is no (That said, I also ❤️ the feature!) |
Beta Was this translation helpful? Give feedback.
-
I mostly use dependent tuples for this: x fin { case x: T => x.underlying } match
case Dep(x, a: A) => ...
case Dep(x, b: B) => ...
case _ => fallback where the core is: type ^:[X, Y <: Dep[_, _]] = Dep[X, Y]
class Dep[X, Y <: _ ^: _](val x: X, val y: PartialFunction[X, Y])
object Dep:
def unapplySeq[A, B <: _ ^: _](c: A ^: B): LazyList[_] =
c.x #:: c.y.unapply(c.x).fold(LazyList.empty)(unapplySeq(_)) and some sugar is added: inline def empty = PartialFunction.empty
extension [X](x: X)
def pure: X ^: Nothing = Dep(x, empty)
def dep[Y <: PartialFunction[X, _ ^: _]](y: Y): X ^: _ = Dep(x, y)
def fin[V, Y <: PartialFunction[X, V]](y: Y): X ^: _ = Dep(x, y andThen Dep.pure) You can try it out here: https://scastie.scala-lang.org/ojlQ9epcQ4O5ZuMxqNyktg. Tuple VS nested match is a matter of preference I think. |
Beta Was this translation helpful? Give feedback.
-
I put up this branch with an implementation using |
Beta Was this translation helpful? Give feedback.
-
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:
I want to match on
T
's that have an underlyingA
orB
and return a fallback for the rest. In current Scala, here's what I need to do:The duplication of
fallback
is annoying, in particular iffallback
is naturally a list of cases by itself.The proposal here is to introduce the following shorthand:
Syntax:
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
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.
Beta Was this translation helpful? Give feedback.
All reactions