I am trying to remove redundancy in my code. I think I can do it with higher order functions.
What I want to do is factor out the common bits into f3, then just make the bits that are different between f1 and f2 be parameters that are passed into f3.
object Example extends App {
case class action(name: String, age: Int) {
def setName(new_name: String): action = this.copy(name = new_name)
def setAge(new_age: Int): action = this.copy(age = new_age)
}
def f1(x: action, increment: Int) = {
// big block of code which does a....
// a single line in the block calling
val older_person = x setAge (x.age + increment)
// big block of code which does b....
}
def f2(x: action, new_name: String) = {
// big block of code which does a....
// a single line in the block calling
val new_name_person = x setName new_name
// big block of code which does b....
}
/* Now as there is clearly a redundancy, which can be solved by higher order functions.
I want to combine f1 and f2 into a single function. The function will take in the action, the value, and the
function to apply. It will then call the relevant function inside the method.
*/
def f3[T](x: action)(f: T => action)(value: T) = {
// big block of code which does a....
// call x.f(value)
val new_action = ???
// big block of code which does b....
}
// then in my code I can call like this:
// f3(x)(setAge)(100)
// f3(x)(setName("new_name")
}
What I am confused about is how can I pass in a function that is a method inside the case class? Is there anyway to do this in an elegant way?
In f3
, you can simply accept a function of type Action => Action
(I'm going to use Action
instead of action
to make it less confusing).
def f3(x: Action)(copy: Action => Action) = {
// big block of code which does a....
// a single line in the block calling
val new_name_person = copy(x)
// big block of code which does b....
}
Then you can define a few helpful functions and use currying to make them easier to use later:
object Action {
def setName(name: String)(action: Action) = action.copy(name=name)
def incAge(inc: Int)(action: Action) = action.copy(age=action.age+inc)
}
And then use it like this:
val x = Action("Foo", 42)
f3(x)(Action.incAge(100))
f3(x)(Action.setName("new_name"))