Javascript中的模式匹配表达式

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 [

我正在用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没有您可能正在谈论的那种模式匹配。当时,需要使用
案例
/
添加它,下面是该提案的一个示例:

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