Javascript中的模式匹配表达式
我正在用JS进行函数式编程。最近我开始使用Daggy来完成简单的模式匹配,但我认为我并没有完全理解它 鉴于此代码:Javascript中的模式匹配表达式,javascript,functional-programming,Javascript,Functional Programming,我正在用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 [
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没有您可能正在谈论的那种模式匹配。当时,需要使用
案例
/添加它,下面是该提案的一个示例:
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阶段,因此可能无法继续,在继续之前可能会发生根本性的变化,并且可能需要数年的时间才能完成这些阶段并进入语言。有一项工作正在进行中
恐怕我现在还不清楚如何将其应用到您的示例中,因为它似乎需要case
的操作数
同时,如果您想要的是简洁,那么一系列的if
/else if
可以相当简洁:
if (a === 1 && !b) foo(y);
else if (a) foo(x);
else if (b === 3 && c === 2) foo(z);
或者JavaScript的开关非常灵活(如果/否则如果,它实际上只是另一种编写的方式):
(我不是在提倡它,只是指出它是一种选择。)JavaScript没有您可能正在谈论的那种模式匹配。当
时,需要使用案例
/添加它,下面是该提案的一个示例:
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阶段,因此可能无法继续,在继续之前可能会发生根本性的变化,并且可能需要数年的时间才能完成这些阶段并进入语言。有一项工作正在进行中
恐怕我现在还不清楚如何将其应用到您的示例中,因为它似乎需要case
的操作数
同时,如果您想要的是简洁,那么一系列的if
/else if
可以相当简洁:
if (a === 1 && !b) foo(y);
else if (a) foo(x);
else if (b === 3 && c === 2) foo(z);
或者JavaScript的开关非常灵活(如果/否则如果,它实际上只是另一种编写的方式):
(我不是提倡它,只是指出它是一个选项。)您可以为数据创建一个包装类,然后使用函数检查条件,并在特定条件满足时执行操作
简单易用,没有任何库
类换行{
建造师(obj){
this.var=obj;
this.done=false;
}
何时(条件,doFn){
如果(!this.done&&condition(this.var)){
this.done=true;
doFn(this.var);
}
归还这个;
}
}
const data=新的换行({
b:3,c:9
});
数据
.什么时候(
d=>d.a===1&&!d.b,
()=>console.log('C1=>y')
)
.什么时候(
d=>d.b==3和d.c!==2,
()=>console.log('C2=>z')
)
.什么时候(
d=>d.a,
()=>console.log('C3=>x')
)
.什么时候(
d=>正确,
()=>console.log('Last stop')
);代码>您可以为数据创建一个包装类,然后使用函数检查条件,并在特定条件满足时执行操作
简单易用,没有任何库
类换行{
建造师(obj){
this.var=obj;
this.done=false;
}
何时(条件,doFn){
如果(!this.done&&condition(this.var)){
this.done=true;
doFn(this.var);
}
归还这个;
}
}
const data=新的换行({
b:3,c:9
});
数据
.什么时候(
d=>d.a===1&&!d.b,
()=>console.log('C1=>y')
)
.什么时候(
d=>d.b==3和d.c!==2,
()=>console.log('C2=>z')
)
.什么时候(
d=>d.a,
()=>console.log('C3=>x')
)
.什么时候(
d=>正确,
()=>console.log('Last stop')
);代码>当然可以用Daggy定义
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
})
}
当然,用Daggy你可以定义
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
})
}
do
是一个保留关键字。。。当
不是关键字时,你会得到一个语法错误,当
不是关键字时,你会得到一个。如果块中只有一条语句,你可以去掉大括号:如果(a==1&&!b)go(y)代码>“改进”在什么意义上?您所做的一切就是将if
更改为when
,在条件上使用[]
而不是()
,并使用:
而不是完全关闭它(没有块的if
)或使用块。如果愿意()可以将if
写在一行上,如果愿意(),甚至可以滥用和&
操作符,这两者都不是更“实用”的,也不是一种改进。(我已将do
更改为foo
,请参见@CertainPerformance的评论)。还添加了缺少的分号,特别是第二种形式不适用于ASI。如果这些分号是独占的,您将希望else
do
是保留关键字。。。当
不是关键字时,你会得到一个语法错误,当
不是关键字时,你会得到一个。如果块中只有一条语句,你可以去掉大括号:如果(a==1&&!b)go(y)代码>“改进”在什么意义上?您所做的一切就是将if
更改为when
,在条件上使用[]
而不是()
,并使用:
而不是完全关闭它(没有块的if
)或使用块。如果愿意()可以将if
写在一行上,如果愿意(),甚至可以滥用和&
操作符,这两者都不是更“实用”的,也不是一种改进。(我已将do
更改为foo
,请参见@CertainPerformance的评论)。还添加了缺少的分号,特别是第二种形式不适用于ASI。如果它们是独占的,则需要else
。