2015年3月13日 星期五

Scala knowledge - Lifting

不算前言
Lifting 追根朔源我是找到Haskell lifting, 應該是functional 概念衍伸出來的意義, 因為 Scala 集合了OOP + Functional 概念, 所以Scala Lifting又有其自己的意義 

就我自己理解過後大概整理出
Lifting原意就有上升的意思, 更進一步就是轉換更加完整, 更高層級

因此Scala的Lifting應用如下

PartialFunction Lifting 

PartialFunction部分函式, 就是針對某些domain set去定義轉換過程
所以本質上就是一個不完整的Function, 只針對某些定義的domain set 做處理(實作code)
沒有定義(實作code)到的就無法處理

那麼Lifting過後就是更進一步將部分函式轉換成完整的Function
完整的Function 是對於所有的domain set都可以處理

但是那些未定義的domain set 還是沒有implement
總不可能自動幫你生code, 也太逆天了
會發生什麼事情就看看這段
 scala> val pf: PartialFunction[Int, Boolean] = { case i if i > 0 => i % 2 == 0}  
 pf: PartialFunction[Int,Boolean] = <function1>  
 scala> pf.lift  
 res1: Int => Option[Boolean] = <function1>  
 scala> res1(-1)  
 res2: Option[Boolean] = None  
 scala> res1(1)  
 res3: Option[Boolean] = Some(false)  

原本的Function定義上就是把 Int => Boolean
所以完整的Function可以針對所有的 Int 做處理, 不管你丟1, 2, 3, ....任何整數都可以處理

然而定義中的PartialFunction pf 只針對 i > 0 代表正整數處理
如果傳入負數or 0 到 pf PartialFunction裡,
因為沒有任何case 定義到, 所以根本無法處理

但 pf 經過 Lifting過後就變成res1 且是完整的Function type
一個完整Function : Int => Option[Boolean]

這就代表, 儘管你傳入尚未定義的負整數
沒有case 去處理
最外層就用Option 的None包起來
這時候 res1 就有辦法處理所有的整數,

這其實就是在原本的PartialFunction外面再包一層過濾
有case的就是 Some
沒有case的就是 None

Method Lefting

Method 在Scala中就只是method
不是一個真正的function
沒有High-order class 的層級可以做應用
因此透過Lifting 來把method 轉換成真正的Function
 scala> def multiply2(i: Int) = i * 2  
 multiply2: (i: Int)Int  
 scala> val f = multiply2 _  
 f: Int => Int = <function1>  
 scala> f(2)  
 res0: Int = 4  

透過method + underscore
就好比 multiply2 _
把method lift to function

Functor Lefting 

Functor概念還沒摸清楚
待續


沒有留言:

張貼留言