2012-09-22 5 views
2

의 목록에 오류를 추가하는 관용적하고 기능적인 방법 나는 다음과 같은 검증 방법이 있습니다 당신은 아이디어를 얻을스칼라 : 오류

def validate(wine: Wine): List[Error] = { 

    var errors = List[Error]() 

    if (Validate.isEmptyWord(wine.name)) { 
    errors ::= ValidationError("name", "Name not specified") 
    } else { 
    if (isDuplicate(wine, "name")) { 
     errors ::= ValidationError("name", "There already exists a wine with the name '%s'".format(wine.name)) 
    } 
    } 

    if (Validate.isEmptyWord(wine.grapes)) { 
    errors ::= ValidationError("grapes", "Grapes not specified") 
    } 

    if (Validate.isEmptyWord(wine.country)) { 
    errors ::= ValidationError("country", "Country not specified") 
    } 

    // more stuff like this and finnally 
    errors.reverse 
} 

당신은 VAR 목록 [피하기 위해 수정할 것입니다 방법 오류]하고 더 많은 기능을합니까?

답변

3

isX 방법 대신 BooleanOption[Error]를 돌려 쓰기, 다음

List(
    Validate.isEmptyWord(wine.name, "name", "Name not specified"). 
    orElse(Validate.isDuplicate(wine.name, "name", "There already exists...")), 
    Validate.isEmptyWord(wine.grapes, "grapes", "Grapes not specified"), 
    ... 
).flatten 

당신은 당신의 오류를해야합니다. 또한 삭제할 수있는 복제본이 많이 있습니다 (예 : "x", "X not specified" 인 경우 "x"을 제공하고 나머지는 isEmptyWord으로 채워 넣기 만하면됩니다).

+0

확실히, 모든 것을 최적화하기 시작했습니다. 팁을 주셔서 감사합니다. – opensas

+0

부울뿐만 아니라 성공 사례에 아무 것도 필요하지 않으면이 방법이 좋습니다. 성공 사례에서 조각에서 대상을 만들 필요가있을 때 스카 파 루트가 좋습니다. – sourcedelica

10

Scalaz은 이런 종류의 문제에 대한 기능적 접근을 매우 쉽게 만드는 Validation 클래스를 제공합니다. this Stack Overflow answerValidation을 사용하는 방법에 대한보다 자세한 예제가 있지만 여기에 스케치를 제공하여 사용자 상황에서 어떻게 작동하는지 보여줍니다.

import scalaz._, Scalaz._ 

def checkNonempty(v: String, name: String, msg: String) = 
    if (v.nonEmpty) v.successNel else ValidationError(name, msg).failNel 

def checkDuplicate(v: String, name: String, msg: String) = 
    if (true) v.successNel else ValidationError(name, msg).failNel 

물론 당신이 당신의 자신을 추가해야합니다

case class Wine(name: String, grapes: String, country: String) 
case class ValidationError(name: String, msg: String) 

이제 우리는 (나는 Scalaz 7을 사용하고 있습니다 주) 검증 방법의 몇 가지를 쓸 수 있습니다 : 나는 다음과 같은 설정을 가정합니다 마지막 줄까지 중복 검사. 그런 다음 우리는 함께 포장 할 수 있습니다

def createWine(name: String, grape: String, country: String) = (
    checkNonempty(name, "name", "Name not specified").flatMap(_ => 
    checkDuplicate(name, "name", 
     "There already exists a wine with the name '%s'".format(name) 
    ) 
) |@| 
    checkNonempty(grape, "grape", "Grape not specified") |@| 
    checkNonempty(country, "country", "Country not specified") 
)(Wine.apply) 

을 이제 우리는 다음처럼 작성할 경우 :

val result: ValidationNEL[ValidationError, Wine] = createWine(
    "Whatever Estates", "Whatever Grape", "U.S." 
) 

우리는 성공 값을 얻을 것이다 :

Success(Wine(Whatever Estates,Whatever Grape,U.S.)) 

을하지만 우리는 그것을 제공하는 경우 잘못된 입력 :

val result: ValidationNEL[ValidationError, Wine] = createWine(
    "", "Some Grape", "" 
) 

누적 된 오류의 목록 :

Failure(
    NonEmptyList(
    ValidationError(name,Name not specified), 
    ValidationError(country,Country not specified) 
) 
) 

당신은 물론, 자신의 검증 논리 롤,하지만 당신은 이런 종류의 일을 많이하고 있다면 Scalaz 같은 라이브러리를 사용하는 것은 아마도 문제가 가치가 있었다.