predicate combinators

Construye una condición a partir de predicados con nombre — and, or, xor, negate, contramap — en lugar de anidar lambdas.

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)

Lección

Todos los operadores de filtrado de la biblioteca toman un predicado: filter, reject, takeWhile, skipWhile, countWhere, partition. Una vez que has puesto nombre a las condiciones — isEven, isPositive, isBlank —, combinarlas no debería costarte una lambda nueva con el parámetro vuelto a tipar cada vez. Estos combinadores son justo eso.

Son una extensión sobre bool Function(T), así que a cualquier predicado que ya tengas le crecen los métodos: una función de nivel superior, un tear-off, un closure guardado o el resultado de otro combinador. Cada uno devuelve un predicado nuevo y no llama a nada hasta que se ejecuta ese predicado.

and y or cortocircuitan exactamente como && y ||: el predicado de la derecha se salta cuando el de la izquierda ya ha decidido, lo que importa cuando es la mitad cara. xor no tiene nada que cortocircuitar y siempre llama a los dos.

contramap es el raro y el útil. Transforma el argumento en vez del resultado — eso es lo que significa el contra —, así que un predicado sobre int pasa a ser un predicado sobre cualquier cosa que puedas convertir en int: isEven.contramap<String>((s) => s.length) prueba la longitud de una cadena sin una palabra sobre cadenas dentro de isEven.

.negate es la forma de getter de extensión del negate de nivel superior: la misma función, alcanzada desde el otro lado. Usa la que se lea mejor en el punto de llamada; isBlank.or(isShort).negate se lee de izquierda a derecha, mientras que negate(...) metería la expresión entera dentro de una llamada.

Demo 1 · and, or, xor, negate

Demo 2 · contramap, y el cortocircuito

Pruébalo tú

Ejercicio: conserva las filas que no están en blanco ni son cortas.

Relacionado: negate — la forma de nivel superior de .negate · not — voltea un solo valor booleano, no un predicado · filter / whereNot — donde suele acabar un predicado compuesto · predicates — los predicados de tipo integrados con los que combinar