我试图将长模式匹配语句中的常见行为分解为干掉我的代码。我们的想法是将公共代码链接到部分函数中,并通过match语句进行评估。我的理想就像是
type pf = PartialFunction[Int, String]
// Our common behaviour
val common: pf = {
case 0 ⇒ "zero"
case 1 ⇒ "one"
}
val a = 2
// speculative match statement with extended behaviour
val b = a match (common orElse {
case 2 ⇒ "two"
case 3 ⇒ "three"
case _ ⇒ "None"
})
不幸的是,匹配语句的参数显然不是部分函数。显然,问题可以使用部分函数来解决,下面的代码可以解决这个问题,但是我输掉了传统的模式匹配语法:
val c: String = (common orElse {
case 2 ⇒ "two"
case 3 ⇒ "three"
case _ ⇒ "None"
}: pf)(a)
下面的例子是我正在寻找的丑陋的一面。如果scala.MatchError
部分函数中未定义参数a
,则编译但失败并返回common
。
val d = common(a) orElse (a match {
case 2 ⇒ "two"
case 3 ⇒ "three"
case _ ⇒ "None"
})
我正在寻找以下答案:
答案 0 :(得分:1)
匹配并没有像捕获一样,最近在这里:
https://github.com/scala/scala/pull/4334
您可以为catch提供部分功能。
catch
很简单,因为它必须是PartialFunction[Throwable, ?]
,但对我而言,模式匹配以相同的方式进行推广并不明显。问题在于详尽的检查,预期的审查者类型,谁知道什么。
答案 1 :(得分:0)
这有什么问题......?
type Pfis = PartialFunction[Int, String]
val common: Pfis = {
case 0 ⇒ "zero"
case 1 ⇒ "one"
}
val a = 2
val other: Pfis = {
case 2 ⇒ "two"
case 3 ⇒ "three"
case _ ⇒ "None"
}
val b = ( common orElse other )( a )
// If you feel like using the "conventional match-case"
val f = common orElse other
val c = a match { case x => f( x ) }
此外,没有conventional pattern matching syntax
...... match
这样的关键字可以被认为是""作为right-associative function
表示a match pf
与a match pf
或pf.apply( a )
非常相同(不完全相同...... pf( a )
不起作用)。< / p>
此外,orElse
用于functional-composition
,所以基本上,你通过orElse
两个partitial函数组成一个新的部分函数。然后你调用这个新的parital-function,就像你使用任何部分函数一样。
我想,如果你理解orElse
做了什么......你会理解第二点的答案。好吧,它失败了,因为您将partial-function
common
应用于参数2
,并且未在2中定义。
另外,还有一件事......即使在common
定义了a
,你也做错了。让我解释一下,
val t = 1
val d = common( t ) orElse ( t match {
case 2 ⇒ "two"
case 3 ⇒ "three"
case _ ⇒ "None"
})
// Now d is same as following,
val k = "one" orElse "None"
// Here, k and d both are actually PartialFunction[Int,Char] = <function1>
// basically, both k and d take an Int i as argument and return the ( character at index i in "one" ) orElse ( character at index i in "None" )
// So,
println( d( 2 ) )
// Will print - e
println( d( 3 ) )
// since "one" does not have index 3, it will return index 3 in "None"
// will print - e
println( d( 4 ) )
// None of "one" and "None" have index 4
// So, you will get - scala.MatchError: 4 (of class java.lang.Integer)