2013-12-15 5 views
3

저는 scalaz7 렌즈를 배우려고합니다. 설정 작업을 연결하는 더 좋은 방법이 있습니까?사슬 Scalaz 렌즈 세트 작업

case class Outer(left: Inner, right: Inner) 
case class Inner(top: Int, bottom: Int) 

val left = Lens.lensu[Outer, Inner](
    (o,v) => o.copy(left = v), 
    _.left 
) 
val right = Lens.lensu[Outer, Inner](
    (o,v) => o.copy(right = v), 
    _.right 
) 
val top = Lens.lensu[Inner, Int](
    (o,v) => o.copy(top = v), 
    _.top 
) 

val leftTop = left >=> top 
val rightTop = right >=> top 

val outer0 = Outer(Inner(10,20), Inner(30, 40)) 
val outer1 = rightTop.set(leftTop.set(outer0, 11), 33) 

업데이트 :

내가 대답은 내가 겨우이 작동하는 것 같다 이유를 이해하지만, 상태 모나드를 사용할 수도 있다는 느낌이 듭니다. 더 깔끔한 방법이 있는지 알고 싶습니다.

val modifier = for{ 
    _ <- leftTop := 11 
    _ <- rightTop := 33 
} yield Unit 

modifier(outer0)._1 // = Outer(Inner(11,20),Inner(33,40)) 

답변

1

당신은 어느 국가 모나드 버전 단순화 할 수 있습니다 : 당신이 원하는 경우,

(leftTop := 11) >> (rightTop := 33) exec outer0 

을 또는 :

val modifier = (leftTop := 11) >> (rightTop := 33) 
modifier.exec(outer0) 

원래 주 버전은 조금 이상한 보인다 이후 for<- 문은 .flatMap에 대한 호출 구문 설탕입니다. 조금 단순화하면 leftTop := 11의 결과는 State[Outer, Outer, Int]과 같은 유형이며, 이는 대략 Outer => (Outer, Int) 유형의 함수와 같습니다. 상태는 결과 중 Outer 부분을 추적하여 Int 부분을 .flatMap으로 전달합니다. Int 결과에 신경 쓰지 않으므로 _에 할당하고 무시하십시오.

(leftTop := 11) flatMap (_ => rightTop := 33) 

이의 결과가를 실행하는 도우미 함수 .exec이있는 주 계산입니다 :

>>은이 인수의 무시하고 서면과 동일한 .flatMap의, 같은 일을 초기 상태 (outer0)로 계산하고 최종 상태를 반환합니다 (결과를 무시함).

State를 사용하지 않으려면 처음 시작한 것처럼해야합니다. 모든 주정부는 명시 적으로 언급하지 않고 단계 간 중간 결과를 전달하는 것입니다.