2012-08-23 18 views
0

我有以下代碼:應用或操作選項將導致

class CSplit(var s1: CanvNode, var s2: CanvNode) extends SplitPane 
{   
    topComponent = s1.merge 
    bottomComponent = s2.merge 
    def containsV(orig: MapCanvT): Option[MapCanvT] = 
    { 
     def containsIn(cn: CanvNode): Option[MapCanvT] = cn match 
     { 
     case Left => None 
     case Right(mc) => if (mc == orig) Some(mc) else None     
     } 
     containsIn(s1) match 
     { 
     case Some(mc) => Some(mc) 
     case None => containsIn(s2) 
     } 
    } 
} 

我想減少containsV方法的代碼。我的第一個想法是使用fold方法來縮短containsIn方法。但是Option沒有,也沒有擴展Class。選項[T]不應該擴展[T,None]嗎?然後至少有一個人可以使用Either的摺疊方法。

我最終的想法是把S1和S2的列表,而在找到它,但我不能讓這個編譯:

def containsV(orig: MapCanvT): 
    Option[MapCanvT] = ::[CanvNode](s1, s2).find(_ == Right(orig))  

回答

1

讓我們先從簡單的部分:

containsIn(s1) match 
    { 
    case Some(mc) => Some(mc) 
    case None => containsIn(s2) 
    } 

相同

containsIn(s1) orElse containsIn(s2) 

現在,我們只需要對付containsIn

def containsIn(cn: CanvNode): Option[MapCanvT] = cn match 
    { 
    case Left => None 
    case Right(mc) => if (mc == orig) Some(mc) else None     
    } 

我們可以在使用foldEither,它擺脫了大部分模式ma tching:

cn.fold(_ => None, Some(_)) 

但是有orig thingy。我們可以用一個過濾器處理它,但:

cn.fold(_ => None, Some(_)) filter (orig.==) 

這樣:

def containsV(orig: MapCanvT): Option[MapCanvT] = { 
    def containsIn(cn: CanvNode): Option[MapCanvT] = 
    cn.fold(_ => None, Some(_)) filter (orig.==) 
    containsIn(s1) orElse containsIn(s2) 
} 

我覺得orElse大大忽視。

+0

感謝您的詳細解答,我一直在使用Either上的fold語法,並且過濾方法將非常有用。 –

5

Scala的2.10增加至foldOption。在此期間,您可以使用map(f).getOrElse(g)代替:

// These produce identical results 
o.fold(g)(x => f(x)) 
o.map(x => f(x)).getOrElse(g) 

編輯:因此,舉例來說,以下三個做同樣的事情:

val os: List[Option[Int]] = List(Some(5),None) 

// Explicit match 
os.map{ _ match { 
    case Some(x) => x+3 
    case None => 0 
}} 

// map+getOrElse 
os.map{ _.map(_+3).getOrElse(0) } 

// fold 
os.map{ _.fold(0)(_+3) } 

fold情況下,你給的默認值首先處理案例None,然後處理存在值的情況下的函數。在每種情況下,您應該得到List(8,0)

+0

我使用2.10.0M5,但用的是2.9.2庫文件來實現。你能告訴我們這個例子的摺疊語法嗎?我無法解決這個問題。 –

2

它可以用列表使用collectFirst方法

def containsV(orig: MapCanvT): Option[MapCanvT] 
    = List(s1, s2).collectFirst {case i: MapCanvT if (i == (orig) => i}