술어 조합자

람다를 중첩하는 대신 이름 붙은 술어로 조건을 짭니다 — and, or, xor, negate, contramap.

extension FxPredicateOps<T> on bool Function(T) bool Function(T) get negate bool Function(T) and(bool Function(T a) other) bool Function(T) or(bool Function(T a) other) bool Function(T) xor(bool Function(T a) other) bool Function(A) contramap<A>(T Function(A a) f)

강의

라이브러리의 거르는 연산자는 모두 술어를 받습니다. filter, reject, takeWhile, skipWhile, countWhere, partition이 그렇습니다. isEven, isPositive, isBlank처럼 조건에 이름을 붙였다면, 그것들을 합칠 때마다 매개변수 타입을 다시 적은 새 람다를 치를 이유는 없습니다. 이 조합자들이 그 자리를 메웁니다.

bool Function(T) 위의 확장이라서, 이미 손에 쥔 술어라면 무엇이든 이 메서드들이 붙습니다. 최상위 함수든, 티어오프든, 변수에 담은 클로저든, 다른 조합자의 결과든 상관없습니다. 각 조합자는 새 술어를 돌려주며, 술어가 실행되기 전까지는 아무것도 호출하지 않습니다.

andor&&, ||와 똑같이 단락합니다. 왼쪽에서 이미 결론이 나면 오른쪽 술어는 건너뜁니다 — 비싼 쪽이 오른쪽일 때 의미가 있습니다. xor는 단락할 것이 없으므로 항상 양쪽을 부릅니다.

contramap은 낯설면서 쓸모 있는 쪽입니다. 결과가 아니라 인자를 변환합니다 — contra가 가리키는 바가 그것입니다. 덕분에 int에 대한 술어가, int로 바꿀 수 있는 무엇에 대한 술어가 됩니다. isEven.contramap<String>((s) => s.length)isEven 쪽에 문자열 이야기를 한마디도 넣지 않고 문자열 길이를 검사합니다.

.negate는 최상위 negate를 확장 게터로 옮겨 놓은 것입니다 — 같은 함수를 반대편에서 부르는 셈이죠. 호출 지점에서 더 잘 읽히는 쪽을 쓰면 됩니다. isBlank.or(isShort).negate는 왼쪽에서 오른쪽으로 읽히지만, negate(...)는 식 전체를 호출 안쪽으로 밀어 넣습니다.

데모 1 · and, or, xor, negate

데모 2 · contramap, 그리고 단락

직접 해 보기

연습: 비어 있지도 짧지도 않은 행만 남겨 보세요.

관련 항목: negate.negate의 최상위 형태 · not — 술어가 아니라 bool 값 하나를 뒤집습니다 · filter / whereNot — 조합한 술어가 보통 놓이는 자리 · predicates — 함께 조합할 내장 타입 술어들