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 :)