Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts

Thursday, 2 July 2009

More Partial Functions

Here I am defining a couple of PartialFunctions and using them:

def main(args :Array[String]) :Unit = {

def f1 : PartialFunction[List[String], String] = {
case "a" :: rest => "I got an A"
}
def f2 : PartialFunction[List[String], String] = {
case "a" :: "b" :: rest => "I got an A and the next letter is a B"
}
def f3 = f2 orElse f1

println( handleRequest2( "a"::"c"::"a"::"b"::Nil)(f3) )
}

def handleRequest2(req : List[String])
(exceptions : PartialFunction[List[String], String]) : String = {
if (req.isEmpty) {
""
} else if (exceptions.isDefinedAt(req)) {
exceptions(req) + "\n" + handleRequest2( req.tail )(exceptions)
} else {
"Normal handle "+req.head+" ..done" + "\n" + handleRequest2( req.tail(exceptions)
}
}


Output [is unsurprisingly]:

I got an A
Normal handle c ..done
I got an A and the next letter is a B
Normal handle b ..done

Saturday, 20 June 2009

Functions passed to functions (delegates)


def turnNumbersToEven() = {
val nums = 1 to 20
println( nums.map(a => addOneToNumberIf(a % 2 == 1)( a)) )
}
def addOneToNumberIf( test : => Boolean)( i : Int) : Int = {
if (test) {
return i + 1
} else {
return i
}
}


Note because we used addOneToNumberIf(a)(b) notation instead of addOneToNumberIf(a,b) notation we are allowed to write scripts {} like this:


def turnNumbersToEven() = {
val nums = 1 to 20
println( nums.map(a => addOneToNumberIf {a % 2 == 1} (a)) )
}

Sunday, 14 June 2009

Functions apply and update

If you have an object with an 'apply' method you dont need to specify apply when calling it. ie: a.apply(20) === a(20)

Similar behavior with 'update' except you can use an '='. I'm currently baffled as to why you'd want to do this: a.update(6, "str") === a(6) = "str"


object Functions {

def main(args :Array[String]) = {
val a = new Ap(6)
println( a.apply(20) + " == " + a(20))
println( a.update(6, "str") + " == " + (a(6) = "str") )
}

}

class Ap(i : Int) {
def apply(in : Int) = (in + i).toString
def update(in : Int, v : String) = println("hey "+in+" "+v)
}

Passing Functions to functions

Obviously unlike java 'basic' is not executed until in the function 'answer'.


object Functions {

def main(args :Array[String]) = {
println("rec: " + answer( basic ))
}

def basic(i : Int) : String = i.toString

def answer( f : Int => String ) = f.apply(42)
}

Friday, 12 June 2009

Functions inside functions

Methods inside methods can reference the variables in the outer methods. Check this:
Note the 'n's:


def drop[T](N: Int, l: List[T]): List[T] = {
def dropR(c: Int, curList: List[T]): List[T] = (c, curList) match {
case (_, Nil) => Nil
case (1, _ :: tail) => dropR(N, tail)
case (_, e :: tail) => e :: dropR(c - 1, tail)
}
dropR(N, l)
}


The above is a Method to remove every 'N'th element in the list.
Note the way they stick the counter on to the head of the list in the case statement.

This is how I did it - a completely different solution. [Is this Java-ery or funky and functional - I'm not sure].

list.zipWithIndex.partition( a => a._2 % count == count-1 )._2.map( a => a._1)