Removing vars from method


#1

Hi everyone,

I’m trying to do something functionally but can’t think how. I am sure there is a succinct way:

Trivial example:

def doSomething(i: Int): Int = i + 1

def doSomethingNTimes(i: Int, n: Int): Int = { var tmp = 0; (1 to n).foreach(tmp = doSomething(tmp)); tmp }

The idea of doSomethingNTimes is to take an object of one my classes, do something N times to it and then have the new object ready to return to assign to another variable.

(I could put doSomething inside doSomethingNTimes but not what I’m focusing on here)
Can this be improved?


#2

Did you mean var tmp = i instead of var tmp = 0? I’ll assume you did.

Here’s a solution using Stream.iterate from the Scala standard library:

def doSomethingNTimes(i: Int, n: Int): Int =
  Stream.iterate(i)(doSomething).apply(n)

As a performance optimization, you could replace Stream.iterate with Iterator.iterate (and replace .apply(n) with .drop(n).next()), but you asked for a pure-functional solution and Iterator is mutable.

So that’s how I would normally write this, but here’s another solution that doesn’t use anything external:

@annotation.tailrec
def doSomethingNTimes(i: Int, n: Int): Int =
  if (n <= 0) i
  else doSomethingNTimes(doSomething(i), n - 1)

#3

Yes, that does it - thanks. A bit like the bang example from the stairway book. I find the recursive answer still doesn’t come naturally, but streams even less so.