Skip to content

Match

match()

进行模式匹配。

  • Details

传入若干组数组一一对应每条规则,每个数组中有两个元素,这里记为 checker 与 executer。

match 将会返回一个函数,该函数接收一定数量的参数,并根据每条规则按顺序匹配第一个符合条件的 checker,执行对应的 executer 并返回结果。

对于每个 checker 的详细检测规则如下:

checker 类型模式匹配参数个数[2]匹配规则
基本量字面值(number/string/object/array[1]/maybe)1将会比较参数与字面值是否相等[3]来判断是否匹配成功
function(sync)任意将匹配值全部传给该函数,根据函数返回的 true/false 信息判断是否匹配成功
arrayArray 长度Array 中可包含前两种匹配方式,将会对每个值采取单独的匹配方式,若都匹配成功则认为匹配成功
otherwise任意采用该方式的匹配总是成功的,用于处理分类为“其他”的情况

对于每个 executer 的执行规则如下:

executer 类型执行规则备注
字面值匹配成功后将直接返回该字面值/
function将匹配值全部传给该函数,并返回该函数的执行结果虽然该函数没有像 checker 那样标注必须为同步函数,但如果是一个返回 Promise 的函数,我们会原样返回一个 Promise 而不对其进行处理

备注:

[1] : 因为 match 的设计依赖于 array 来进行分类,所以当您想编写匹配一个 array 字面量的逻辑时,请为其多套一层数组(可见下文例子)。

[2] : 此列只作标识作用,实际通过 match 返回的函数的 length 属性的值为 0。

[3] : match 对于 number/string 的相等规则与 equalStrict 相同;对于 object/array 的相等规则与 deepEqual 相同;对于 maybe 的相等规则为 按 equalStrict 规则比对 fold 后的值。

  • 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.