You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to #52, scoped down from it: today's CaptureMatcher.unapplySeq (Capture.scala:84, landed in 5bee7d5) is Seq-based, mirroring scala.util.matching.Regex.unapplySeq - case myMatcher(g1, g2) => ... works, but arity is checked structurally at the match site against a runtime Seq, not against a fixed tuple type.
Why it's Seq and not Tuple2/Tuple3/...:CaptureMatcher.numGroups (Capture.scala:68) is a runtime value, only known after CaptureMatcher.parse(pattern: String) (Capture.scala:91) parses a fully dynamic string. CaptureMatcher itself carries no type-level trace of that arity - two instances built from "(a)(b)" vs "(a)(b)(c)" have the identical type CaptureMatcher. A Tuple-returning unapply needs the arity fixed in the type the compiler sees at the case myMatcher(g1, g2) => site, which a single def unapply(...) on the class can't vary per-instance.
What a tuple-returning variant would need:
Arity known at Scala compile time, i.e. the pattern must be a literal (inline/macro), not an arbitrary runtime String - CaptureMatcher.parse can't serve this, since it's explicitly the dynamic, Either[RegexParseError, CaptureMatcher]-returning entry point.
A decision on where this lives: extending CaptureMatcher with an inline compile-time-literal entry point alongside the existing runtime parse, vs. a wholly separate type.
Not a small tweak to the existing unapplySeq - it's a distinct compile-time-macro feature, so splitting it out of #52 rather than reopening scope there.
Follow-up to #52, scoped down from it: today's
CaptureMatcher.unapplySeq(Capture.scala:84, landed in 5bee7d5) isSeq-based, mirroringscala.util.matching.Regex.unapplySeq-case myMatcher(g1, g2) => ...works, but arity is checked structurally at the match site against a runtimeSeq, not against a fixed tuple type.Why it's
Seqand notTuple2/Tuple3/...:CaptureMatcher.numGroups(Capture.scala:68) is a runtime value, only known afterCaptureMatcher.parse(pattern: String)(Capture.scala:91) parses a fully dynamic string.CaptureMatcheritself carries no type-level trace of that arity - two instances built from"(a)(b)"vs"(a)(b)(c)"have the identical typeCaptureMatcher. ATuple-returningunapplyneeds the arity fixed in the type the compiler sees at thecase myMatcher(g1, g2) =>site, which a singledef unapply(...)on the class can't vary per-instance.What a tuple-returning variant would need:
inline/macro), not an arbitrary runtimeString-CaptureMatcher.parsecan't serve this, since it's explicitly the dynamic,Either[RegexParseError, CaptureMatcher]-returning entry point.CaptureMatcher[N <: Int & Singleton]) or a distinct macro-produced carrier type, echoing howTokenMatcheris already a separate compiled artifact rather than bolted ontoRegex(see Support case myRegex(g1, g2) => ... pattern matching once capturing groups exist #52's own "Needs a decision on the carrier type" note, and the precedent in Add a compile-time macro that builds TokenMatcher's DFA, not just parses to Regex #51 for macro-time compilation of a literal pattern set).CaptureMatcherwith aninlinecompile-time-literal entry point alongside the existing runtimeparse, vs. a wholly separate type.Not a small tweak to the existing
unapplySeq- it's a distinct compile-time-macro feature, so splitting it out of #52 rather than reopening scope there.