문제

나는 밀봉된 특성이 구현되는 의해 3 개

sealed trait MyTrait {
...
}
object A extends MyTrait { ... }
object B extends MyTrait { ... }
object C extends MyTrait { ... }

내가 사용하여 Scalaz 의 유효성 검사 메커니즘 상의 적용 방법의 개체,B 및 C 반환된 형식입니다.체는 A,B 및 C 이 포함되지 않은 몇 가지 논리에 적용하고 싶 이 논리는 순차적으로,즉,내가 원하는 최초 적용하고 확인 것의 결과이며,이를 기반으로 결정하려는 경우 호 B 또는 반환 검증 결과입니다.내가 반복하려는 이 때까지 치 C 후에는 내가 다 내가 무엇을 얻는 결과로 전화 C.

현재 갖고 있는 정적 접근이 어디서 처음 호출,전달의 결과를 유틸리티 방법 및 확인에 대한 결과는 다음 전화 B.

  def apply(request: Request): Validated[Result] = {
    val vResultA = run(request, A)
    val vResultB = if (isResultOk(vResultA)) run(request, B) else vResultA
    if (isResultOk(vResultB)) run(request, C) else vResultB
  }

더 좋은 방법이 있을까요?어떤 제안이 있거나는 패턴을 적용할 수 있?

도움이 되었습니까?

해결책

을 정의합니다 성공 결과 결과는 확인, 고 실패는 결과=하지 않은 결과는 확인.

첫째, A, B, 고 C 은 모든 물체를 확장 MyTrait.따라서,그들은 그들로 그룹화할 수 있습니다이나 배열 목록 MyTrait.

val objects = Array(A, B, C) /* You can use List instead if you want. */

다음의 유형 objectsArray[MyTrait].

다음으로,우리는이 있을 반복 적용할 수 있는 이 배열입니다.
그러나,그냥 전화 map 이 배열을 계속 매핑하는 경우에도 이전 isResultOk()false.
따라서,우리가 사용하는 StreamArray.

보 방법을 사용하여 Stream 수단 map 는 경우 몇 가지 조건이 만족하고 있습니다.

Array(1, 2, 3, 4, 5).map(i => {
    println(i)
    i + 100
  }).takeWhile(_ <= 103).foreach(println(_))

출력 위의 코드:

1
2
3
4
5
101
102
103

그래서, map() 끝,그리고 다음 takeWhile() 끝-- takeWhile() 에 영향을 미치지 않는 전화 map().
그러나 우리가 할 경우에 대해 동일한 작업 Stream,

Array(1, 2, 3, 4, 5).toStream.map(i => {
    println(i)
    i + 100
  }).takeWhile(_ <= 103).foreach(println(_))

출력은 다음과 같습니다.

1
101
2
102
3
103
4

그래서 호출 될 것입니다 map() -> takeWhile() -> foreach() -> map() -> takeWhile() -> ...
끝에서,4 인쇄,그리고 4+100=104>103 것을 잘라에서 takeWhile().
다음 요소가 될 것입니다 액세스하지 않습니다.

그래서,우리가 사용하 takeWhile?

objects.toStream.map(run(request, _)).takeWhile(isResultOk(_))

이것은 제거하지 못한 결과,비록 우리가 필요한 첫 번째 실패한 결과 실패하는 경우 발생했습니다.
(i.e이 문제가 있으면 결과는 확인되지 않습니다.)

는 방법에 대해 반대수 dropWhile()?

objects.toStream.map(run(request, _)).dropWhile(isResultOk(_))

이것은 모두 제거 성공한 결과,경우에도 모든 결과에 성공했습니다.
(i.e이 경우 문제가 모든 결과를 확인합니다.)

그래서,우리가 사용하는 span().
c.span(p) = (c.takeWhile(p), c.dropWhile(p))
우리는 것입 테스트가 있는 경우는 결과가 확인되지 않습니다.
이 있는 경우 그 결과는지 확인,우리는 반환됩니다 첫 번째 이러한 결과입니다.
그렇지 않으면,우리는 것을 반환 마지막 결과 확인을 누릅니다.

val (succ, fail) = objects.toStream.map(run(request, _)).span(isResultOk(_))
fail.headOption.getOrElse(succ.last)

fail.headOptionSome(fail's first element) 는 경우 fail 비어 있지 않은,그렇지 않으면 None.

에 요약

val objects = Array(A, B, C)

def apply(request: Request): Validated[Result] = {
  val (succ, fail) = objects.toStream.map(run(request, _)).span(isResultOk(_))
  fail.headOption.getOrElse(succ.last)
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top