Skip to content

Commit 6209ceb

Browse files
committed
feat(patterns): Expand special-casing of "optionality" patterns
Rather than limiting the special behavior to `M.or(M.undefined(), other)`, also apply it to `M.or(undefined, other)` and to reversed-order analogs (i.e., `other`-first).
1 parent 84716b7 commit 6209ceb

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

packages/patterns/src/patterns/patternMatchers.js

+21-9
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,16 @@ const makePatternKit = () => {
304304
*/
305305
const isKind = (specimen, kind) => checkKind(specimen, kind, identChecker);
306306

307+
/**
308+
* Checks if a pattern matches only `undefined`.
309+
*
310+
* @param {any} patt
311+
* @returns {boolean}
312+
*/
313+
const isUndefinedPatt = patt =>
314+
patt === undefined ||
315+
(isKind(patt, 'match:kind') && patt.payload === 'undefined');
316+
307317
/**
308318
* @param {any} specimen
309319
* @param {Key} keyAsPattern
@@ -777,15 +787,17 @@ const makePatternKit = () => {
777787
X`${specimen} - no pattern disjuncts to match: ${q(patts)}`,
778788
);
779789
}
780-
if (
781-
patts.length === 2 &&
782-
!matches(specimen, patts[0]) &&
783-
isKind(patts[0], 'match:kind') &&
784-
patts[0].payload === 'undefined'
785-
) {
786-
// Worth special casing the optional pattern for
787-
// better error messages.
788-
return checkMatches(specimen, patts[1], check);
790+
// Special case disjunctions representing a single optional pattern for
791+
// better error messages.
792+
const binaryUndefPattIdx =
793+
patts.length === 2
794+
? patts.findIndex(patt => isUndefinedPatt(patt))
795+
: -1;
796+
if (binaryUndefPattIdx !== -1) {
797+
return (
798+
specimen === undefined ||
799+
checkMatches(specimen, patts[1 - binaryUndefPattIdx], check)
800+
);
789801
}
790802
if (patts.some(patt => matches(specimen, patt))) {
791803
return true;

0 commit comments

Comments
 (0)