Search code examples
scalasicp

How to invoke a function which takes function parameters?


Watching the SICP course https://www.youtube.com/watch?v=erHp3r6PbJk&index=3&list=PLB63C06FAF154F047 I have converted some of the lisp code to Scala :

def sumInt(a: Int, b: Int): Int = {     //> sumInt: (a: Int, b: Int)Int
  if(a > b) 0
  else a + sumInt(1 + a, b)
}                                               

sumInt(3, 5)                            //> res0: Int = 12

def sumSquares(a: Int, b: Int): Int = { //> sumSquares: (a: Int, b: Int)Int
  if(a > b) 0
  else (a * a) + sumSquares(1 + a, b)
}                                               

sumSquares(2, 3)                        //> res1: Int = 13

To make a more generic function which accepts the functions as parameters to compute the squares instead of coding them within the function I've added :

def sum(term: Int => Int, a: Int, next: Int => Int, b: Int): Int = {
  if(a > b) 0
  else {
    val toAdd1 = term(a)
    val toAdd2 = toAdd1 + sum(term, next(a), next, b)
    toAdd1 + toAdd2
  }
}   

But I'm unsure how to invoke this function? Can this be made more generic so that parameters a & b do not have to be of type Int?


Solution

  • The invocation is as simple as doing :

    println(sum({x=>x},1,{x=>x+1},4))
    

    For a more generic why to write this function, you can use scala Numeric:

    def sumG[A](term: A => A, a: A, next: A => A, b: A)(implicit n: Numeric[A]): A = {
      if(n.compare(a,b)>0) 
          n.zero
      else
         n.plus(term(a),sumG(term, next(a), next, b))
    }
    

    this call it like this:

    println(sumG[Int]({x=>x},1,{x=>x+1},4))