Wednesday, October 10, 2012

Scala, recursion and meta-function literals

I'm 3 weeks in to the Functional Programming in Scala course at Coursera.org, and I've just knocked out this week's assignment. I was so shocked at part of the solution, I've reproduced it here (with enough changes to comply with Coursera's honour code, natch).
object GetThis {
    
  def matchAny( predicates: List[ Int => Boolean]): Int => Boolean =
  { 
     (x: Int) => if( predicates.isEmpty) false
       else if( predicates.head(x)) true
       else matchAny(predicates.tail)(x)
  }
  
  def matchAll( predicates: List[ Int => Boolean]): Int => Boolean =
  { 
     (x: Int) => if( predicates.isEmpty) true
       else if( predicates.head(x)) matchAll(predicates.tail)(x)
       else false
  }

  val possible= List( 1,2,3,4,5,6,7,8,9,10,20,30,40,50,99)
  
  val conditions= List(
    (x: Int) => x % 2 ==0, 
    (x: Int) => x % 5 ==0, 
    (x: Int) => x > 5 
  ) 
  
  val matchedAny= possible.filter( matchAny(conditions))
  
  val matchedAll= possible.filter( matchAll(conditions))
}
So, you can see that I

  • create a list of integers, called 'possible'
  • build a list of function literals that specify functional maps from ints to booleans (which is pretty cool, but not the really cool bit)
  • use the filter method on the list of possible integers (which is a tiny bit cool, but not the really cool bit). 
 The magical bit happens with the matchAny / matchAll functions (meta-functions, perhaps). They take a list of predicates (each predicate maps ints to booleans) and combines them into a single predicate-applying function. They both are defined recursively, testing the predicate at the front of the list, and recursing with the tail. So these functions are returning a function (I think) that is defined in terms of further applications of itself. That is the really cool bit :)