可以为所应用的参数值提取或询问部分应用的函数

时间:2013-10-12 03:53:57

标签: scala

是否有办法提取或询问部分应用的函数以获取应用值。 例如,可以在下面的代码中从reduceBy3中提取值3。

def subtract(x:Int, y:Int) = x-y
val reduceBy3 = subtract(3,_:Int)

我已尝试创建一个提取器,如下例所示,但是unapply方法必须接受需要询问的(Int => Int)函数。

class ReduceBy(y: Int) {
  val amt = y
  def subtract(y: Int, x: Int) = x - y
}

object ReduceBy extends Function1[Int, Int => Int] {
  def apply(y: Int) = {
    val r = new ReduceBy(y)
    r.subtract(y, _: Int)
  }
  def unapply(reduceBy: ReduceBy): Option[Int] = Some(reduceBy.amt)
}

object ExtractPartialApplied extends App {
  val r3 = ReduceBy(3)
  val extract = r3 match {
    case ReduceBy(x) => ("reduceBy", x)
    case x: ReduceBy => ("reduceBy", x.amt)
    case _ => ("No Match", 0)
  }

  println(extract)
  val z = r3(5)
  println(z)
}

2 个答案:

答案 0 :(得分:0)

你可以让你的subtract方法接收第一个参数,然后返回一个类似函数的对象,然后接受第二个参数,类似于多参数列表函数,但是你可以扩展它但是你希望。

虽然这看起来并不优雅,但需要一些手动样板。

class ReduceBy(val amt: Int) {
  def subtract(x: Int) = {
    val xx = x // avoid shadowing
    new Function[Int, Int] {
      def x = xx
      def apply(y: Int) = x - y
    }
  }
}

答案 1 :(得分:0)

适应danielkza答案的解决方案是让伴随对象进行提取并返回一个保留初始值的ReduceBy函数。

object ReduceBy {
  def apply(y: Int) = new ReduceBy(y) 
  def unapply(reduceBy: ReduceBy): Option[Int] = Some(reduceBy.amt)
}    

class ReduceBy(val amt: Int) extends Function[Int, Int] {
  def apply(y: Int) = y - amt
} 

object ExtractPartialApplied extends App {
  val reduceBy3 = ReduceBy(3)
  val extract = reduceBy3 match {
    case ReduceBy(x) => ("ReduceBy(x)", x)
    case x: ReduceBy => ("ReduceBy", x.amt)
    case _ => ("No Match", 0)
  }
  println(extract)
  println(reduceBy3(5))
}