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)
```
I originally wanted to do that, but I don't think you can.
Everything inherits an equals(x: Any) method. 
if we override that, then this would compile:
```
val x = Column[Int]
x == "hello" // compiles
```

If instead I try to make a method named `==` or `equals` that takes a T as an argument, then if you use the correct type when calling `==` it does what we'd want, but when you use the wrong type it falls back to the `equals(x: Any)` method.