通过取消应用功能丰富PartialFunction [英] enrich PartialFunction with unapply functionality
问题描述
PartialFunction
是自然提取器,其lift
方法提供了确切的提取器功能.因此,使用部分函数作为提取器将非常方便.这将允许以比PartialFunction
PartialFunction
is a natural extractor, its lift
method provides exact extractor functionality. So it would be very convenient to use partial functions as extractors. That would allow to combine pattern matching expressions in more complicated way than plain orElse
that is available for PartialFunction
所以我试图用皮条客的库方法,但是失败了
So I tried to use pimp my library approach and had failed
此处更新:如@Archeg所示,还有另一种有效的转换方法.因此,我将其包含在提供的代码中.
Here goes update: As @Archeg shown, there is another approach to conversion that works. So I'm including it to the provided code.
我也尝试了一些更复杂的解决方案,但失败了
I'm tried also some more complex solutions and they failed
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不是case类,也没有unapply/unapplySeq成员 情况f(i)=> println(i)
UnapplyImplicitly.scala:16: error: value f is not a case class, nor does it have an unapply/unapplySeq member case f(i) => println(i)
UnapplyImplicitly.scala:28:错误:预期为'=>',但找到了'('. case toUnapply(f)(i)=> println(i)
UnapplyImplicitly.scala:28: error: '=>' expected but '(' found. case toUnapply(f)(i) => println(i)
可以按照所示的TestI
形式避免此错误.但是我很好奇是否有可能避免testInplace
错误:
This errors may be avoided with supposed form as TestI
shown. But I'm curious if it is possible to avoid testInplace
error:
UnapplyImplicitly.scala:46:错误:简单模式的非法启动 case {case"bingo" => 0} .u(i)=> println(i) ^
UnapplyImplicitly.scala:46: error: illegal start of simple pattern case { case "bingo" => 0 }.u(i) => println(i) ^
UnapplyImplicitly.scala:47:错误:预期为"=>",但为;"成立. case _ => println("nothing")
UnapplyImplicitly.scala:47: error: '=>' expected but ';' found. case _ => println("nothing")
UnapplyImplicitly.scala:56:错误:预期为"=>",但为."成立. 案例g("bingo").u(i)=> println(i) ^
UnapplyImplicitly.scala:56: error: '=>' expected but '.' found. case g("bingo").u(i) => println(i) ^
推荐答案
我不确定最终要实现的目标,但是据我了解,提取器应该始终是对象,因此您无法采取任何措施上一堂课.它在文档中实际上称为Extractor Object
.考虑一下:
I'm not sure what you are trying to achieve in the end, but as far as I understand extractors should always be objects, there is no way you can get it with a class. It is actually called Extractor Object
in the documentation. Consider this:
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") }
}
这篇关于通过取消应用功能丰富PartialFunction的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!