Reputation: 346
I am trying to use function composition, but I am not sure how to make this work with parameterless methods.
The following code functionally does what I need it to do:
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)
}
Here is how I would like to express that functionality:
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")
Perhaps my question should be, why is there no andThen method defined on Function0?
As suggested, changing the signature to a Function1 (by using a unit: Unit parameter) seems like the least involved "fix".
Another, more involved workaround, would have been something such as:
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")
Upvotes: 1
Views: 213
Reputation: 6385
andThen
is the function that accepts two arguments of Function1
type, so you have to represent you functions as Function1
It can be done by redefining calculateLastWeek
as
def calculateLastWeek = (z: Unit) => ReportPeriod(forDay.minus(7), forDay)
then you can write
val x = calculateLastWeek andThen renderPeriod
x()
Upvotes: 1
Reputation: 1066
Perhaps my question should be, why is there no andThen method defined on Function0?
andThen
is only defined on Function1
because it uses the outcome of the first function as an argument to the second. If Function0
would have an andThen
method the result of the first method would be lost.
Upvotes: 1
Reputation: 15086
Are you not just looking for renderPeriod(calculateLastWeek)
? Unless this is for some kind of DSL.
Upvotes: 1