我正在通过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)
答案 0 :(得分:2)
JavaScript可能没有您正在谈论的模式匹配。有an active proposal使用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)
}
}
它目前仅处于the process的第1阶段,因此它可能不会进行,可能会在进行之前发生根本性的变化,并且可能需要数年的时间才能完成各个阶段并使用该语言。 Babel plugin上有工作。
不过,恐怕我现在还不清楚如何将其应用于您的示例,因为它似乎想要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;
}
(我不主张这样做,只是指出这是一种选择。)
答案 1 :(得分:0)
您可以为数据创建包装器类,然后使用函数检查条件,并在满足特定条件的情况下采取措施。
简单易用,没有任何库。
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 => d.a === 1 && !d.b,
() => console.log('C1 => y')
)
.when(
d => d.b === 3 && d.c !== 2,
() => console.log('C2 => z')
)
.when(
d => d.a,
() => console.log('C3 => x')
)
.when(
d => true,
() => console.log('Last stop')
);
答案 2 :(得分:0)
确定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))