Suppose I have the following class:
public class FixExpr {
Expr in;
}
Now I want to introduce a generic argument, abstract
Still, there are ways to encode higer-kinded generics in Java. Please, have a look at higher-kinded-java project.
Using this as a library, you can modify your code like this:
public class Fix {
Type.App> in;
}
You should probably add an @GenerateTypeConstructor annotation to your Expr class
@GenerateTypeConstructor
public class Expr {
// ...
}
This annotation generates ExprTypeConstructor class. Now you can process your Fix of Expr like this:
class Main {
void run() {
runWithTyConstr(ExprTypeConstructor.get);
}
void runWithTyConstr(ExprTypeConstructor.Is tyConstrKnowledge) {
Expr> one = Expr.lit(1);
Expr> two = Expr.lit(2);
// convertToTypeApp method is generated by annotation processor
Type.App> oneAsTyApp = tyConstrKnowledge.convertToTypeApp(one);
Type.App> twoAsTyApp = tyConstrKnowledge.convertToTypeApp(two);
Fix oneFix = new Fix<>(oneAsTyApp);
Fix twoFix = new Fix<>(twoAsTyApp);
Expr> addition = Expr.add(oneFix, twoFix);
process(addition, tyConstrKnowledge);
}
void process(
Fix fixedPoint,
ExprTypeConstructor.Is tyConstrKnowledge) {
Type.App> inTyApp = fixedPoint.getIn();
// convertToExpr method is generated by annotation processor
Expr> in = tyConstrKnowledge.convertToExpr(inTyApp);
for (Fix subExpr: in.getSubExpressions()) {
process(subExpr, tyConstrKnowledge);
}
}
}