Skip to content

Match

match()

Performs pattern matching.

  • Details

Takes several pairs of arrays corresponding to each rule; each array contains two elements, referred to here as checker and executer.

match will return a function that accepts a certain number of arguments. It will then sequentially evaluate each checker and, upon the first successful match, execute the corresponding executer and return its result.

Detailed matching rules for each checker are as follows:

checker TypeNumber of Matching Parameters[2]Matching Rule
Basic Literal Values (number/string/object/array[1]/maybe)1Compares the argument with the literal value for equality[3] to determine match success
Function (synchronous)AnyPasses all matching values to the function and determines match success based on the function's true/false return value
ArrayLength of ArrayThe array can contain the first two types of matchers. Each value is matched individually. All must succeed for the array to match.
otherwiseAnyAlways succeeds when used, suitable for handling "other" cases

Execution rules for each executer are as follows:

executer TypeExecution RuleNote
LiteralImmediately returns this literal value when match succeeds
FunctionPasses all matching values to the function and returns the function's resultAlthough the function is not explicitly marked as synchronous like checker, if it returns a Promise, the Promise will be returned as-is

Notes:

[1]: Because match's design relies on arrays for classification, when you want to match an array literal, you should nest it inside another array (see examples below).

[2]: This column is for identification purposes only; the actual length property value of the function returned by match will be 0.

[3]: match uses the same equality rules for numbers/strings as equalStrict, for objects/arrays as deepEqual, and for maybe as comparing the folded values using equalStrict.

  • Example
Example 1
js
const sort = match(
	[[[]], []],
	[
		_,
		([x, ...xs]) => [
			...sort(filter(lte(x), xs)),
			x,
			...sort(filter(gt(x), xs))
		]
	]
);

const fib = match(
    [1, 1],
    [2, 2],
    [_, (v) => fib(v - 1) + fib(v - 2)]
);
const sort = match(
	[[[]], []],
	[
		_,
		([x, ...xs]) => [
			...sort(filter(lte(x), xs)),
			x,
			...sort(filter(gt(x), xs))
		]
	]
);

const fib = match(
    [1, 1],
    [2, 2],
    [_, (v) => fib(v - 1) + fib(v - 2)]
);
Example 2
js
// Data Nat = Succ Nat | Zero
const Nat = Data('Succ m', 'Zero');
Object.assign(global, Nat.binder);

// instance Show Nat
Nat.bindShow(match(
    [Zero.is, 0],
    [Succ.is, ({ m }) => m.show() + 1]
));

// add :: Nat -> Nat -> Nat
// add n Zero = n
// add n (Succ m) = Succ (add n m)
const add = match(
	[[_, eqData(Zero)], (n, _) => n],
	[[_, eqData(Succ(_))], (n, { m }) => Succ(add(n, m))]
);

add(Succ(Succ(Zero)), Succ(Zero)).show(); //3
// Data Nat = Succ Nat | Zero
const Nat = Data('Succ m', 'Zero');
Object.assign(global, Nat.binder);

// instance Show Nat
Nat.bindShow(match(
    [Zero.is, 0],
    [Succ.is, ({ m }) => m.show() + 1]
));

// add :: Nat -> Nat -> Nat
// add n Zero = n
// add n (Succ m) = Succ (add n m)
const add = match(
	[[_, eqData(Zero)], (n, _) => n],
	[[_, eqData(Succ(_))], (n, { m }) => Succ(add(n, m))]
);

add(Succ(Succ(Zero)), Succ(Zero)).show(); //3

PureEval released under the GPL-3.0 License.