Thursday, December 29, 2011

Learning Scala : Reading the exotic and essential List API scaladoc 8

Authored by Win Myo Htet

def andThen [C] (k: (A) ⇒ C): PartialFunction[Int, C]
Composes this partial function with a transformation function that gets applied to results of this partial function.
def lift : (Int) ⇒ Option[A]
Turns this partial function into an plain function returning an Option result.
def orElse [A1 <: Int, B1 >: A] (that: PartialFunction[A1, B1]): PartialFunction[A1, B1]
Composes this partial function with a fallback partial function which gets applied where this partial function is not defined.
We toggle the Ordering in the search section to By Inheritance. The above three functions are inherited from PartialFunction. We know that PartialFunction are a very powerful feature derived from the Functional Programming. Let's see how we can apply that to List.
scala> val list: List[Int] = List(1, 2, 3, 4)
list: List[Int] = List(1, 2, 3, 4)

scala> val lsqr=list.andThen(x=> x +" square is "+(x*x))
lsqr: PartialFunction[Int,java.lang.String] = <function1>

scala> lsqr(0)
res0: java.lang.String = 1 square is 1

scala> lsqr(3)
res1: java.lang.String = 4 square is 16

scala> val optionList=list lift
optionList: Int => Option[Int] = <function1>

scala> optionList(0)
res2: Option[Int] = Some(1)

scala> optionList(-1)
res3: Option[Int] = None

scala> optionList(3)
res4: Option[Int] = Some(4)

scala> optionList(4)
res5: Option[Int] = None

scala> val outOfRange:PartialFunction[Int,String]={case x=>x+" is out of Range."}
outOfRange: PartialFunction[Int,String] = <function1>

scala> val safelsqr= lsqr orElse outOfRange
safelsqr: PartialFunction[Int,java.lang.String] = <function1>

scala> safelsqr(0)
res6: java.lang.String = 1 square is 1

scala> safelsqr(-1)
res7: java.lang.String = -1 is out of Range.

scala>  safelsqr(3)
res8: java.lang.String = 4 square is 16

scala> safelsqr(4)
res9: java.lang.String = 4 is out of Range.

scala> val lcompose=list.compose((x:Int)=> x match{ case x if x< 0 => -x; case x => x})
lcompose: Int => Int = <function1>

scala>  lcompose(-1)
res10: Int = 2

We declare val list and then we define PartialFunction andThen, which return String composed of the value x and its square value. Since we are applying andThen to list the x value comes from list, which return the value for the index we give to lsqr. lift make use of the Option monad pattern(concept like Design Pattern but more powerful and abstract). The return function from lift will return value wrapped in Option. Why lift? One might wonder the choice of the word. The term comes from the Mathematics, which Functional Programming has based upon. The Option monad concept has lifted the unsafe value to the safe value wrapped in the Option, thus even when we feed the index out of range, the function does not blow up. If we feed the out of range index to our lsqr function created from andThen, it will blow up (which is ugly and thus omitted from the code demo.) That is where orElse came in. We define the Partial Function outOfRange and combine that with orElse to create a new function safelsqr. Now our safelsqr can handle out of range index without blowing up.

def compose [A] (g: (A) ⇒ Int): (A) ⇒ A
I have squeezed in compose function. The example code snippet is not a very good one(if you have a good example, please share with us). The reason is that compose mirrors andThen in a functional sense. There is a github blog from twitter on that. Let's go to apply.

Authored by Win Myo Htet

No comments:

Post a Comment