PartialFunction
是一个自然提取器,其lift
方法提供精确的提取器功能。因此,使用部分函数作为提取器非常方便。这将允许以比orElse
PartialFunction
更复杂的方式组合模式匹配表达式
所以我尝试使用pimp my library方法而且失败了
这里有更新:正如@Archeg所示,还有另一种转换方法可行。所以我将它包含在提供的代码中。
我也尝试了一些更复杂的解决方案而且失败了
object Test {
class UnapplyPartial[-R, +T](val fun : PartialFunction[R,T]) {
def unapply(source : R) : Option[T] = fun.lift(source)
}
implicit def toUnapply[R,T](fun : PartialFunction[R,T]) : UnapplyPartial[R,T] = new UnapplyPartial(fun)
class PartialFunOps[-R, +T](val fun : PartialFunction[R,T]) {
def u : UnapplyPartial[R, T] = new UnapplyPartial(fun)
}
implicit def toPartFunOps[R,T](fun : PartialFunction[R,T]) : PartialFunOps[R,T] = new PartialFunOps(fun)
val f : PartialFunction[String, Int] = {
case "bingo" => 0
}
val u = toUnapply(f)
def g(compare : String) : PartialFunction[String, Int] = {
case `compare` => 0
}
// error while trying to use implicit conversion
def testF(x : String) : Unit = x match {
case f(i) => println(i)
case _ => println("nothing")
}
// external explicit conversion is Ok
def testU(x : String) : Unit = x match {
case u(i) => println(i)
case _ => println("nothing")
}
// embedded explicit conversion fails
def testA(x : String) : Unit = x match {
case toUnapply(f)(i) => println(i)
case _ => println("nothing")
}
// implicit explicit conversion is Ok
def testI(x : String) : Unit = x match {
case f.u(i) => println(i)
case _ => println("nothing")
}
// nested case sentences fails
def testInplace(x : String) : Unit = x match {
case { case "bingo" => 0 }.u(i) => println(i)
case _ => println("nothing")
}
// build on the fly fails
def testGen(x : String) : Unit = x match {
case g("bingo").u(i) => println(i)
case _ => println("nothing")
}
// implicit conversion without case is also Ok
def testFA(x : String) : Option[Int] =
f.unapply(x)
}
我收到以下错误消息:
UnapplyImplicitly.scala:16:错误:值f不是案例类,也没有unapply / unapplySeq成员 case f(i)=>的println(ⅰ)
UnapplyImplicitly.scala:28:错误:'=>'预期但'''发现。 case toUnapply(f)(i)=>的println(ⅰ)
如果显示TestI
所谓的形式,可以避免这种错误。但我很好奇是否可以避免testInplace
错误:
UnapplyImplicitly.scala:46:错误:非法启动简单模式 case {case“bingo”=> 0} .u(i)=>的println(ⅰ) ^
UnapplyImplicitly.scala:47:错误:'=>'预期,但';'找到。 case _ =>的println( “无”)
UnapplyImplicitly.scala:56:错误:'=>'预期,但'。'找到。 case g(“bingo”)。u(i)=>的println(ⅰ) ^
答案 0 :(得分:4)
我不确定你到底想要实现什么,但据我所知,提取器应该总是对象,你无法用类来获得它。它实际上在文档中称为Extractor Object
。考虑一下:
class Wrapper[R, T](fun: PartialFunction[R, T]) {
object PartialExtractor {
def unapply(p: R): Option[T] = fun.lift(p)
}
}
implicit def toWrapper[R,T](fun : PartialFunction[R,T]) : Wrapper[R, T] = new Wrapper(fun)
val f : PartialFunction[String, Int] = {
case "bingo" => 0
}
def testFF(x : String) : Unit = x match {
case f.PartialExtractor(i) => println(i)
case _ => println("nothing")
}
<强>更新强>
我能想到的最好的:
def testInplace(x : String) : Unit ={
val ff = { case "bingo" => 0 } : PartialFunction[String, Int]
x match {
case ff.PartialExtractor(Test(i)) => println(i)
case "sd" => println("nothing") }
}