I am designing some polymorphic code to perform mathematical operations. The idea is to abstract out the underlying representation of the data, as different use cases require different representations. Operations can only be performed with data of the same type.
There are many algorithms operating on these things and as these algorithms require a lot of operations. Therefore IMO the best design is to create a base interface defining polymorphic operations and have each data type be an implementation of that interface:
interface Datum<D extends Datum<D>> {
D fuzz();
D fuse(D that);
D fizz(int base);
}
class MadDatum extends Datum<BigDatum> {
...
}
However, I also need certain constants to be defined for each representation. I would like to access these constants polymorphically so that generic algorithms that are agnostic to the implementation of Datum
can cleanly obtain constants of the correct type. As constants don't depend on a Datum
, it doesn't really make sense to define them as methods there. But the only reasonable alternative that I can think of is to create a parallel type hierarchy representing the type of data:
interface DataType<D extends Datum<D>> {
D warpTorsion();
D meltingAngle();
}
But then methods need to take both the type and the data:
<D extends Datum<D>> D newmansMethod(DataType<D> type, Collection<D> data);
This design is awkward because it duplicates the class hierarchy in a way that the compiler doesn't check - one can easily implement Data and forget to implement a corresponding DataType - and it requires an extra method parameter in possibly hundreds of methods.
I am aware that Haskell admits an elegant solution to this problem because it allows constants / "nullary functions" to be specified in type classes. Does anyone know a clean way to replicate this functionality in Java?
DataType<D>
?Datum
, sayMadDatum
, might not have a correspondingMadDataType
, which would mean you couldn't callnewmansMethod<MadDatum>
, but you would only notice that issue downstream when you actually try to callnewmansMethod
.