Reputation: 1738
What is an idiomatic way of chaining function calls, passing results between each with parameters supplied on the way in Scala?
Here's an example:
def a(x : A, param : String) : A = x
def b(x : A, param : String) : A = x
def c(x : A, param : String) : A = x
def d(x : A, param : String, anotherParam : String) : A = x
val start = A()
d(c(b(a(start, "par1"), "par2"), "par3"), "par4", "anotherPar")
One approach that comes to my mind is Ruby's Kernel#yield_self
which allows to do the following:
start
.yield_self {|x| a(x, "par1") }
.yield_self {|x| b(x, "par2") }
.yield_self {|x| c(x, "par3") }
.yield_self {|x| d(x, "par4", "anotherPar) }
Upvotes: 3
Views: 2156
Reputation: 44957
I'd say that chaining functions using well... chaining isn't that bad already:
(
{ (x: A) => a(x, "par1") } andThen
{ x => b(x, "par2") } andThen
{ x => c(x, "par3") } andThen
{ x => d(x, "par4", "anotherPar") }
)(start)
However, if you insist on having a yieldSelf
method, here you go:
import scala.language.implicitConversions
case class YieldSelf[X](x: X) {
def yieldSelf[Y](f: X => Y): Y = f(x)
}
implicit def everythingCanYieldSelf[X](x: X) = YieldSelf(x)
start.
yieldSelf{ a(_, "par1") }.
yieldSelf{ b(_, "par2") }.
yieldSelf{ c(_, "par3") }.
yieldSelf{ d(_, "par4", "anotherPar") }
As soon as the implicit definition is in the scope, it adds a yieldSelf
method to every object, which has the same semantics as in Ruby.
Upvotes: 3
Reputation: 10681
You may combine chain of functions into one function:
val start = new A()
val func: (A => A) =
((x: A) => a(x, "par1"))
.andThen(b(_, "par2"))
.andThen(c(_, "par3"))
.andThen(d(_, "par4", "anotherPar"))
func(start)
But I'm not sure if it's a your goal.
Upvotes: 3