Modify function passed as argument - scala

I have two functions. One is masterChecker, wich takes as argument an Int x and a function p, and return the boolean result p(x). Simple like that.
def masterChecker(x: Int, p: Int => Boolean): Boolean = p(x)
Then I have a second function childChecker, which is like an alias to masterChecker
def childChecker(x: Int, f: Int => Boolean): Boolean = masterChecker(x , f)
Is there any way to change f in the masterCheker call on childChecker, in a manner that it would run like !f ? (if f return true, than make it false)
Like:
// inside childChecker
masterChecker(x, !f)
I know that I could do it on the masterChecker call with !masterChecker(x,f), but what I want to know is if it´s possible to change a function behavior passed as an argument.

Sure, you can use an anonymous function like so:
def childChecker(x: Int, f: Int => Boolean) = masterCheck(x, !f(_))
and there you go!
Even more so, you could do a number of things if you want to "modify" f within the function scope of childChecker:
def childChecker(x: Int, f: Int => Boolean) ={
def proxy(x: Int): Boolean ={
val y: Int = //do things
f(y) //see? "y" not "x"
}
masterCheck(x, proxy)
}
that's part of the fun when you're dealing with plain ol' functions. Granted, this "modification" is more of a decorator pattern but it does adhere to the interface.

Related

Addressing parameter function's parameter in a scala method

It's probably obvious, but it's making me crazy and I think my code is being bloated as a result (missing the obvious, not the making me crazy part).
I have a method as follows:
def fun(f: Int => Boolean, y: Int): Int
This method is going to be called like this fun(*some anon func*, y) and should increase and return y + 1 when some anon function (applied to some param) is greater than 0 and y - 1 otherwise. How to define fun? I'm trying something like
def fun(f: Int => Boolean, y: Int): Int =
if (f) y - 1
else y + 1
Obviously, that doesn't work. I should put f(tmp), where tmp:Int but I'm now sure how to express that.
All examples I could find online always apply f on y, but this is just funny.
Update: here's a similar problem I have already solved, but am not happy with how did I do it:
For a given function forall(s: Set, p: Int => Boolean): Boolean, which returns true iff all the set elements x in S (def S: int => Boolean, indicator function for set S) satisfy p(x), create a function that will implement exists quantifier (exists function). In set theory, one can express this quantifier as (in terms of the problem described above) not all elements (not forall) of a set satisfy NOT p.
I did something like this:
def exists(s: Set, p: Int => Boolean): Boolean = {
def negP(x: Int): Boolean = !p(x)
!forall(s, negP)
}
My question is: how to do this without defining negP? I cannot state !p because Scala gives error for ! operator. I cannot use !p(x) because there is no x. Hence the problem above and my question.
TIA
You could make it return a function that does that, like so:
def fun(f: Int => Int, y: Int): Int => Int =
input => if (f(input) > 0) y - 1 else y + 1
val test1 = fun(x => x*2, 1)
println(test1(-1)) // "2"
val test2 = fun(x => x - 100, 5)
println(test2(101)) // "4"
val test3 = fun(x => x, -10)
println(test3(0)) // "-9"
EDIT: Note that I changed the signature of the input function, as I think it probably reflects the requirements better, changing it back to boolean should be trivial(see other answers). :)
EDIT(2):
Seeing is you updated your question, I thought best to update my answer: You can always just inline a function, in your example, maybe you could do it like this:
def exists(s: Set, p: Int => Boolean): Boolean = !forall(s, x => !p(x))
Your original problem can't be solved because you can't test the output of f() without invoking f(), and you can't invoke f() without an input argument to pass. I think the best you can hope for is something like this.
def fun(f: Int => Boolean, y: Int): Int => Int = (arg: Int) =>
if (f(arg)) y - 1
else y + 1
Your "similar problem" looks to me like it should be a different question.
Your proposed solution can be solved via recursion, but using forall() it can be expressed more concisely.
def exists(s: Set[Int], p: Int => Boolean): Boolean =
!forall(s, (x:Int) => !p(x))
It sounds like you don't actually want to pass a parameter to your anonymous function? Then try this:
def fun(f: () => Boolean, y: Int): Int =
if (f()) y - 1
else y + 1

Scala anonymous function (creating a new function based on one passed)

I've a function where I'm trying to modify a function I've been passed (p) in an anonymous function, then use it as a parameter to f2.
Here's the code;
def f1(i: Int, p: Int => Boolean): Boolean = {
!f2(s,(a :Int=>Boolean) = !p(a) )
}
def f2(i: Int, p: Int => Boolean): Boolean
But this won't compile due to missing markers, and I'm a bit stumped.
James
Maybe you want to try and do this:
def f1(i: Int, p: Int => Boolean): Boolean = {
!f2(i,(a :Int=>Boolean) = !p )
}
def f2(i: Int, p: Int => Boolean): Boolean
Gzou was right, the problem I had was not including a space between the => and !. Thanks for that, very helpful,

What is the purpose of outer and inner function parameters in Scala?

In the following code:
def product(f: Int => Int)(a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f)(a + 1, b)
The parameters a and b are passed to the inner function, but you could write exactly the same function definition like so:
def product(f: Int => Int, a:Int, b:Int): Int =
if (a > b) 1
else f(a) * product(f, a + 1, b)
So what is the purpose of separating the parameters? In other words, why do this:
(f: Int => Int)(a:Int, b:Int)
when you can more clearly write:
(f: Int => Int, a:Int, b:Int)
Another feature of multiple parameters lists is partial application:
def sum3(a: Int)(b: Int)(c: Int): Int = a + b + c
val g: Int => Int => Int = sum3(10) _
val h: Int => Int = g(20)
val r: Int = h(30) // 10 + 20 + 30 = 60
You can partially apply a function and obtain another function which is equivalent to the original one but with one of the arguments fixed. _ after sum3(10) is needed because sum3 is a method, not a function, and _ converts methods to functions.
This is very useful when you are using higher-order functions:
def adder(x: Int)(y: Int) = x + y
Seq(1, 2, 3, 4) map adder(10) // Seq(11, 12, 13, 14)
When partially applied method/function is used as an argument of a higher-order call, _ is not needed, and the syntax becomes very succinct.
Another use case of this feature is that if you want to create a control structure that looks like it's built into Scala programming language itself.
For example, I could write an control structure named times which help me execute the code block exactly n times by the following method definition:
// since block is call by name, it will not be evaluate when you call it.
def times(n: Int)(block: => Any): Unit = {
for (i <- 0 until n) {
block // evaluate(execute) block
}
}
// Now I can use the times method like a control structure
times(5) {
println("Hello World");
}
It depends whether there is implicit parameter (which can't be properly mixed with plain ones)...
def foo(i: Int)(implicit p: P): Foo
... and the way you want to call it ...
def foo1(a: Int)(b: Int => Boolean): Boolean
foo1(9) { i => false }
def foo2(a: Int, b: Int => Boolean): Boolean
foo2(9, { i => false })

Scala and Writing map functions

So suppose I have a function that expects a Set with definition Int => Boolean and a function f like this:
def map(s: Set, f: Int => Int): Set = {}
Now how do I apply this f to each element of this set s.
def map(s: Set, f: Int => Int): Set = { (i: Int) => f(s(i)) }
Which is ofcourse incorrect because in f(s(i)), 's(i)' returns a boolean, and thus can't apply f on it. Problem is how do I access each element of Set and apply this f on it?
This question is part of Coursera's Functional Programming with Scala course.
A goal of the course is to help you understand the functional model, and in this case, how the Set can be represented by a function (called the charasteristic function for that set).
Instead of the final solution, here's a hint on how to reason about this problem:
Given the characteristic function f: Int => Boolean that defines your set and x, an Int, if f(x) == true, then x belongs to the Set. Now, if you have a function g:Int=>Int
that you want to map over the set, what you want is to apply that function to the elements that you know that belong to the set: if (f(x)) then g(x).
Try to apply that thinking to your exercise.
If you wrote the exists function correctly:
def map(s: Set, f: Int => Int): Set = (i: Int) => exists(s, (x: Int) => i == f(x))
Bam one line!
You need to use fold to do this.
def map(s: Set[Int], f: Int => Int): Set[Int] =
s.foldLeft(Set.empty[Int])((s,i) => s+f(i))

reversing the boolean return type from a function

I have two functions which accept a function type: Int => Boolean function type
def myFunction1(f1: Int => Boolean) ...
def myFunction2(f2: Int => Boolean) ...
I want to call function2 from function1 but instead of just invoking it with f1, I want to invoke it with the inverse of f1. So if f1 is something like
(x: Int) => x > 4
at runtime, i.e. return true for numbers greater than four. I want the reverse returns false if numbers are greater than four. Is it possible to inverse f1 before calling myFunction2?
You could do something like this:
def myFunction1(f1: Int => Boolean) = myFunction2(!f1(_))
def myFunction1(f1: Int => Boolean) = myFunction2(f1 andThen (! _))