Reputation: 2555
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
Upvotes: 0
Views: 164
Reputation: 51271
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))
Upvotes: 1
Reputation: 480
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))
Upvotes: 1
Reputation: 1045
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
Upvotes: 0