[英]Pattern matching expressions in Javascript
我正在通过 JS 进行函数式编程。 最近开始用Daggy来完成简单的模式匹配,但是我觉得还没有完全搞定。
鉴于此代码:
if(a === 1 && !b) {
do(y)
}
if(b === 3 && c === 2) {
do(z)
}
if (a) {
do(x)
}
有没有办法将这种凝聚力改进为类似于?:
when [a === 1 && !b] : do(y)
when [a] : do(x)
when [b === 3 && c === 2]: do(z)
JavaScript可能没有您正在谈论的那种模式匹配。 有一个积极的建议使用case
/ when
添加它,这是该建议的示例:
const res = await fetch(jsonService)
case (res) {
when {status: 200, headers: {'Content-Length': s}} -> {
console.log(`size is ${s}`)
}
when {status: 404} -> {
console.log('JSON not found')
}
when {status} if (status >= 400) -> {
throw new RequestError(res)
}
}
不过,它目前仅处于流程的第1阶段,因此它可能不会进行,可能会在进行之前发生根本性的变化,并且可能需要数年的时间才能完成各个阶段并使用该语言。 有一个Babel插件的工作。
恐怕我现在还不清楚如何将其应用于您的示例,因为它似乎需要case
的操作数。
同时,如果您正在寻找简洁,则一系列if
/ else if
可能会相当简洁:
if (a === 1 && !b) foo(y);
else if (a) foo(x);
else if (b === 3 && c === 2) foo(z);
或JavaScript的switch
异常灵活(实际上,这只是另一种写if
/ else if
):
switch (true) {
case a === 1 && !b: foo(y); break;
case a: foo(x); break;
case b === 3 && c === 2: foo(z); break;
}
(我不主张这样做,只是指出这是一个选择。)
您可以为数据创建包装器类,然后使用函数检查条件,并在满足特定条件的情况下采取措施。
简单易行,无需任何库。
class typeWrap { constructor(obj) { this.var = obj; this.done = false; } when (condition, doFn) { if (!this.done && condition(this.var)) { this.done = true; doFn(this.var); } return this; } } const data = new typeWrap({ b: 3, c : 9 }); data .when( d => da === 1 && !db, () => console.log('C1 => y') ) .when( d => db === 3 && dc !== 2, () => console.log('C2 => z') ) .when( d => da, () => console.log('C3 => x') ) .when( d => true, () => console.log('Last stop') );
当然,有了Daggy,您可以定义Maybe
const Maybe = daggy.taggedSum('Option', {
Just: ['a'],
Nothing: []
})
然后在其上定义一个原型函数alt
,该函数基本上可以回退到传递的值
// alt :: Alt f => f a ~> f a -> f a
Maybe.prototype.alt = function(o): Maybe<T> {
return this.cata({
Just: _ => this,
Nothing: () => o
})
}
因此,我们可以进行一些模式匹配或类似的操作
function match(comparator, res) {
switch (comparator()) {
case true: return Maybe.of(res)
case false: return Maybe.Nothing
default: return Maybe.Nothing
}
}
MaybeF.Nothing
.alt(match(() => a === 1 && !b, () => y))
.alt(match(() => a, () => x))
.alt(match(() => b === 3 && c === 2, () => z))
Patron 的开发者和维护者。 我一直在寻找 js 风格的模式匹配,不得不自己构建。 这是您的示例使用 patron 库的样子:
const isNil = x => !(x != null)
patroon(
{a: 1, b: isNil}, y,
{b: 3, c: 2}, z,
{a: _}, x
)({a, b, c})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.