2012-08-23 3 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 방법의 코드를 줄이고 자합니다. 나의 첫번째 생각은 접는 방법을 사용하여 containsIn 메소드를 줄이는 것이었다. 그러나 Option에는 하나도 없으며 Class Either를 확장하지도 않습니다. Option [T]는 [T, None] 중 하나를 확장해서는 안됩니까? 그러면 적어도 하나는 양쪽의 접는 방법을 사용할 수 있습니다.

내 마지막 생각은 S1과 목록으로 S2 처리하고 그 위에 찾을 수 있습니까했지만, 난이 컴파일 얻을 수 없습니다

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

답변

1

의이 쉬운 부분부터 시작하자 :

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

우리는에 fold를 사용할 수 있습니다

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

우리는 containsIn 처리해야 이제

containsIn(s1) orElse containsIn(s2) 

과 동일 Either은 패턴 ma의 대부분을 제거합니다. 응시 :

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

하지만 여기에는 orig 건이 있습니다. 우리는하지만, 필터로 처리 할 수 ​​있습니다 : 따라서

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

자세한 답변을 주셔서 감사합니다. 둘 중 하나의 구문에 어려움을 겪었으므로 필터 방법이 매우 유용합니다. –

5

스칼라 2.10 Optionfold을 추가합니다. 한편 대신 map(f).getOrElse(g)를 사용할 수 있습니다

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

편집 : 당신은 기본값을주는 fold 경우

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

: 그래서, 예를 들어, 다음과 같은 세 가지가 같은 일을 None 먼저 케이스를 처리 한 다음 값이있는 케이스를 처리하는 함수를 호출합니다. 각각의 경우에 List(8,0)을 얻어야합니다.

+0

내가 2.10.0M5를 사용하고있어 collectFirst 방법을 사용하지만, 2.9.2 라이브러리 문서를 사용했다하여 목록으로 구현 될 수있다. 이 예제의 폴드 구문을 보여 주시겠습니까? 나는 그것을 해결할 수 없다. –

2

는 그것은

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