通过取消应用功能丰富PartialFunction [英] enrich PartialFunction with unapply functionality

查看:77
本文介绍了通过取消应用功能丰富PartialFunction的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆