Skip to main content
1 of 3
r3dst0rm
  • 406
  • 3
  • 7

As pointed out as a comment, I was unhappy about the extractCondition function. This function handles, variables which do conform your Predicate<T> type. Which is fine, but I think this doesn't belong here. Because a Predicate should have an accept or, if we talk about the Java implementation, test function. This is not given when we can pass on any random function which do return a boolean. But does not conform our design of a Predicate.

Next naming, the PredicateBuilder seems okay-ish, but it feels wrong. As it isn't a builder in the classical sense. Furthermore we have to work around functional interfaces, and this is I think the main pain point. To achieve this I would propose to rename the Predicate<T> interface, as it should be describing what a Predicate holds (a function which takes a parameter and returns a boolean). Therefore the name Predicate is available again and should be used instead of PredicateBuilder.

The repetition regarding and, or, etc... feels also some kind off. But I think that's because you always do extractCondition and other stuff (I've eliminated this in my suggestion, as the Java Predicate implementation does basically the same). Plus I've create a static method Predicate#of(...) to easier "get" a new Predicate. This reduces the mess a bit, but changing the operands is also still a bit clumsy, in my opinion.

Oh and btw. I've felt free to use arrow functions :-)

interface InternalPredicate<T> {
  (x: T) : boolean
}

class Predicate<T> {
  constructor(private condition: InternalPredicate<T>) {}

  public static of = <T>(condition: InternalPredicate<T>) => {
    return new Predicate(condition);
  }

  public and = (input: Predicate<T>): Predicate<T> =>
    Predicate.of((x: T) => this.apply(x) && input.apply(x));

  public or = (input: Predicate<T>): Predicate<T> =>
    Predicate.of((x: T) => this.apply(x) || input.apply(x));

  public not = (): Predicate<T> =>
    Predicate.of((x: T) => !this.apply(x));

  public apply = (x: T): boolean => this.condition(x);
}

Those are my two cents to the Predicate implementation, feel free to discuss them with me.

r3dst0rm
  • 406
  • 3
  • 7