Add a (more constrained) API for expressing filters on columns

This is to support predicate push down, which will take advantage of these constrained filter predicates.
This will need to be reconciled with the column filters currently in the `parquet.filter` package, but I wanted to get feedback on this first.

Sample usage in java:
```
// if you lie, and column "a.b.c" isn't an int column, we won't know until runtime. 
Column<Integer> abc = column("a.b.c"); 
Column<Double> xyz = column("x.y.z");

FilterPredicate predicate =
      and(not(or(eq(abc, 7), eq(abc, 17))), gtEq(xyz, 100.0));
```

Sample usage in scala:
```
val abc = Column[Int]("a.b.c")
val xyz = Column[Double]("x.y.z")
val predicate = !((abc === 7) || (abc === 17)) && (xyz >= 100.0)
```
Oh, you probably typed `Eq<T>` and the `<T>` disappeared cuz html.

I'm not sure how I could add a type back in here though. I can't change `FilterPredicate` to `FilterPredicate<T>` because of things like this:

```
val x = Column[Int]("x")
val y = Column[Double]("y")
val pred: FilterPredicate = x === 7 || y === 12.0
```
Here pred would be an `Or` of an `Eq<Int>` and a `Eq<Double>`

I could probably do:
`boolean <T> visit(Eq<T> eq);`
but does that buy anything?

I would like to find a way to make this more safe if you have suggestions.