Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have this function definition which takes an r and applies the function f n times:

r => (1 to n).foldLeft(r)((rx, _) => f(rx))

So for n=3 this is equivalent to f(f(f(r)))

I don't like this solution, because it defines a Range from 1 to n which really isn't get used at all, which becomes obvious in the unused parameter _ in the fold left. This in turn forces me to give a separate name to rx which feels wrong to me.

Any idea how I can streamLine this code?

share|improve this question

3 Answers 3

up vote 4 down vote accepted

What's wrong with straight recursion?

def ntimes[A](n:Int, f:A=>A, a:A):A = if (n==0) a else ntimes(n-1, f, f(a))

Another clean option is

Iterator.iterate(a)(f).drop(n).next
share|improve this answer

What about lazy evaluation, using Streams?

def applyFunc[A]( f : A => A, a :A  ) : Stream[A] = f( a ) #:: applyFunc( f, f(a) )

Then for example you could use it like so:

def addOne( i :Int ) = i + 1

val succs = applyFunc( addOne, 0 )

val firstThreeResults= succs.take( 3 ).toList

val onlyFifthResult = succs( 4 )

Of course, if f is a heavy computation, you could also calculate the result as an intermediate step:

  def applyFunc[A]( f : A => A, a :A  ) : Stream[A] = {

    val res = f( a )

    res #:: applyFunc( f, res )
  }
share|improve this answer

I found one alternative, which at least spares the number Range:

r => Array.fill(n)(f(_)).reduce((f1, f2) => x => f1(f2(x)))(r)

But I find the reduce part rather verbose and hard to read.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.