Algebraic Type System

72 views
Skip to first unread message

Roger Wernersson

unread,
Nov 14, 2024, 8:25:17 AM11/14/24
to Project Lombok
I would like for Java to have an algebraic type system like F# does, where I can go

type Alpha=...
type Beta=...
type MyResult = Alpha | Beta

implemented something like this maybe:

interface Alpha {
  int total();
}

interface Beta {
  String name();
}

class MyResult {
  final Alpha alpha;
  final Beta beta;
 
  MyResult(Alpha alpha) {
    this.alpha = alpha;
    this.beta = null;
  }
 
  MyResult(Beta beta) {
    this.alpha = null;
    this.beta = beta;
  }
}

class Example {
  List<MyResult> list = new ArrayList<>();
}



With clever annotations on MyResult so that I don't have to implement all those constructors.

Whadyathink?

Linnea Gräf

unread,
Nov 15, 2024, 12:48:24 PM11/15/24
to project...@googlegroups.com

Something Similar can be achieved in newer Java versions with sealed types:

sealed interface MyResult permits MyResult.Alpha, MyResult.Beta {

    record Alpha(int total) implements MyResult {}

    record Beta(String name) implements MyResult {}

}


You can further match using enhanced switch statements:


void consumeResult(MyResult result) {

    switch (result) {

        case MyResult.Alpha alpha: System.out.println("Total: "+alpha.total()); break;

        case MyResult.Beta beta: System.out.println("Name: "+beta.name()); break;

    }

}


This is sadly only available in higher versions, but similar inheritance structures can be used to implement ADTs in lower versions. If you can't create sealed classes, you will need to use an if else branching system, as well as a (package) private constructor to restrict instantiations through other means.


Is this something along the lines of what would be useful to you?



Roger Wernersson

unread,
Nov 18, 2024, 3:51:57 AM11/18/24
to Project Lombok
Not from a type perspective. I would need several different interfaces/classes like MyResult, each refering to the same implementation of Alpha and Beta, without Alpha and Beta ever knowing anything about those interfaces.

In F# I can go

type Alpha=...
type Beta=...
type Delta=...
type Gamma=...
type ABResult = Alpha | Beta
type ADResult = Alpha | Delta
type AGResult = Alpha | Gamma
type BDGResult = Beta | Delta | Gamma

Reply all
Reply to author
Forward
0 new messages