Scala:使用无参数方法的组合

时间:2016-02-17 13:57:20

标签: scala

我正在尝试使用函数组合,但我不知道如何使用无参数方法使其工作。

以下代码在功能上完成了我需要它做的事情:

import org.joda.time.DateTime

def buildWeekReport(forDay: DateTime, where: String) = {

  case class ReportPeriod(from: DateTime, to: DateTime)

  def calculateLastWeek(day: DateTime) = ReportPeriod(day.minus(7), day)

  def renderPeriod(period: ReportPeriod) = s" we pretend to store $period to $where"

  (calculateLastWeek _ andThen renderPeriod)(forDay)
}

以下是我想表达该功能的方法:

def buildWeekReport3(forDay: DateTime, where: String) = {

  case class ReportPeriod(from: DateTime, to: DateTime)

  def calculateLastWeek() = ReportPeriod(forDay.minus(7), forDay)

  def renderPeriod(period: ReportPeriod) = s" we pretend to store $period to $outputPath"

  calculateLastWeek _ andThen renderPeriod
}

buildWeekReport3(DateTime.now, "c:/temp")

也许我的问题应该是,为什么在Function0上没有定义andThen方法?

正如所建议的,将签名更改为Function1(使用单位:单位参数)似乎是最少涉及“修复”。

另一个更复杂的解决方法可能是:

case class MyFunction0[+R](val fn0: Function0[R]) {
  def andThen[A](g: (R) ⇒ A): () ⇒ A = () => g(fn0())
}

implicit def fn0ToMyFn0[R](fn0: Function0[R]) = new MyFunction0(fn0)

def buildWeekReport4(forDay: DateTime, where: String) = {

  case class ReportPeriod(from: DateTime, to: DateTime)

  def calculateLastWeek = ReportPeriod(forDay.minus(7), forDay)

  def renderPeriod(period: ReportPeriod) = s" we pretend to store $period to $where"


  (calculateLastWeek _ andThen renderPeriod)()
}

buildWeekReport4(DateTime.now, "c:/temp4") 

3 个答案:

答案 0 :(得分:1)

andThen是接受Function1类型的两个参数的函数,因此您必须将函数表示为Function1

可以通过将calculateLastWeek重新定义为

来完成

def calculateLastWeek = (z: Unit) => ReportPeriod(forDay.minus(7), forDay)

然后你可以写

  val x = calculateLastWeek andThen renderPeriod
  x()

答案 1 :(得分:1)

您是否只是在寻找renderPeriod(calculateLastWeek)?除非这是针对某种DSL的。

答案 2 :(得分:1)

  

也许我的问题应该是,为什么在Function0上没有定义andThen方法?

andThen仅在Function1上定义,因为它使用第一个函数的结果作为第二个函数的参数。如果Function0具有andThen方法,则第一种方法的结果将会丢失。