hummingBird
hummingBird

Reputation: 2555

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

Upvotes: 0

Views: 164

Answers (3)

jwvh
jwvh

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

Raudbjorn
Raudbjorn

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

Ossip
Ossip

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

Related Questions