2011-04-21 6 views
10

우리는 프로젝트에서 스카 파 유효성 검사 특성을 사용하여 HTTP 매개 변수의 유효성을 검증합니다. 일반적인 경우, 그렇지 않으면 오류의 목록을 반환 몇 검증 값을 복용하고 그들 모두가 유효한 경우에만이 켜지지 작업을 수행한다 :Scalaz 유효성 검증 및 ApplicativeBuilder 한계

(pavam1Val.liftFailNel |@| 
param2Val.liftFailNel |@| 
param3Val.liftFailNel) { 
    getSomeResponse(_, _, _) 
} 

우리는 8 개 이상의 매개 변수를 사용하기 때문에 할 때까지가, 좋은 일 | @ | operator는 8 개의 인수로 제한되는 ApplicativeBuilder를 생성합니다. 코드를 읽을 수있게 유지하는 것이 좋습니다.

+2

우리는 다음 릴리스에서 12 ApplicativeBuilder''의 (임의의) 한계를 업데이트했습니다. – retronym

답변

11

map (또는 원하는 경우 )으로의 단일 호출과 함께 <*> 메서드를 사용하려고합니다. <*>은 계속 무기한 사용할 수 있습니다. 그것을 할 수

scala> val param1Val = success[String, Int](7)        
param1Val: scalaz.Validation[String,Int] = Success(7) 

scala> val param2Val = failure[String, Int]("abc")       
param2Val: scalaz.Validation[String,Int] = Failure(abc) 

scala> val param3Val = success[String, Int](9)        
param3Val: scalaz.Validation[String,Int] = Success(9) 

scala> val r = param1Val <*> (param2Val <*> (param3Val map getSomeResponse)) 
r: scalaz.Validation[String,Int] = Failure(abc) 
+2

'getSomeResponse'가 카 트리 함수 여야한다는 것을 잊지 마십시오. 즉, Int => Int => Int => Int'입니다. – retronym

+2

논쟁의 순서가 반대가되지 않습니까? 우리가'param3Val <*> (param2Val <*> (param1Val map getSomeResponse))'라고 쓰는 것과 같은 결과를 얻는 것을 의미합니다. – CheatEx

+0

@CheatEx 역순에 대해 정확합니다 – ron

2

몇 가지 더 많은 방법 :

  1. 리프트 Validation 문맥에 관련 기능을 다음 값에 적용합니다.

    getSomeResponse.lift[({ type L[X] = Validation[Y, X] })#L] apply (
        param1Val, param2Val, param3Val 
    ) 
    
  2. 모나드 독해력을 사용하십시오.

    for { 
        x1 <- param1Val 
        x2 <- param2Val 
        x3 <- param3Val 
    } yield getSomeResponse(x1, x2, x3) 
    
+3

물론 모나드 버전은 첫 번째 오류에 대한 오류를 누적하지 않습니다. ron, – ron

+0

. 언급 했어야했다. – missingfaktor

+0

여기에서, 리프팅은 Functor 인스턴스를 사용하므로 너무 빠져 나갑니다. – ron