Account, Transaction, Balance
deposit, withdraw, transfer
withdraw operation requires sufficient funds
Multiple deposits and withdrawals result in same final balance regardless of order
public record TextStyle(Font font, Weight weight){}
public enum Font { SERIF, SANS_SERIF, MONOSPACE }
public enum Weight { NORMAL, LIGHT, HEAVY }
TextStyle = Font ⨯ Weight
9 = 3 x 3
Type A = Integer | Boolean
Type B = String | Float
Type C = A + B
4 = 2 + 2
DnsRecord(AValue(ttl, name, ipv4)
| AaaaValue(ttl, name, ipv6)
| CnameValue(ttl, name, alias)
| TxtValue(ttl, name, value))
DnsRecord(ttl, name, AValue(ipv4)
| AaaaValue(ipv6)
| CnameValue(alias)
| TxtValue(value))
\( \color{orange} (a \cdot b + a \cdot c) \Leftrightarrow a \cdot (b + c) \)
\( \color{blue} (a \cdot b) \Leftrightarrow (b \cdot a) \)
\( \color{red} (a + b) \Leftrightarrow (b + a) \)
\( \color{green} (a + b) + c \Leftrightarrow a + (b + c) \)
\( \color{purple} (a \cdot b) \cdot c \Leftrightarrow a \cdot (b \cdot c) \)
union vals {
char ch;
int nt;
};
struct tagUnion {
char tag; // Tag to track the active type
union vals val;
};
data Shape = Circle Float | Rectangle Float Float
sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(width: Double, height: Double) extends Shape
interface Circle { kind: "circle"; // Discriminant radius: number; } interface Rectangle { kind: "rectangle"; // Discriminant width: number; height: number; } type Shape = Circle | Rectangle;
function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "rectangle": return shape.width * shape.height; } }
enum Task {
NotStarted,
Started,
Completed,
Cancelled;
}
sealed interface TaskStatus{
record NotStarted(...) implements TaskStatus
record Started(...) implements TaskStatus
record Completed(...) implements TaskStatus
record Cancelled(...) implements TaskStatus
}
enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6);
private final double mass; // in kilogram
private final double radius; // in metres
private Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double mass() { return mass; }
public double radius() { return radius; }
}
sealed interface Celestial {
record Planet(String name, double mass, double radius)
implements Celestial {}
record Star(String name, double mass, double temperature)
implements Celestial {}
record Comet(String name, double period)
implements Celestial {}
}
Handle operations on different data types within a hierarchy of objects without modifying the structure of those objects themselves.
sealed interface Shape permits Circle, Rectangle, Triangle, Pentagon { <T> T accept(ShapeVisitor<T> visitor); }
interface ShapeVisitor<T> { T visit(Circle circle); T visit(Rectangle rectangle); T visit(Triangle triangle); T visit(Pentagon pentagon); }
record Circle(double r) implements Shape { public <T> T accept(ShapeVisitor<T> visitor) { return visitor.visit(this); } }
record Rectangle(double w, double h) implements Shape { public <T> T accept(ShapeVisitor<T> visitor) { return visitor.visit(this); } }
record Triangle(double s1, double s2, double s3) implements Shape { public <T> T accept(ShapeVisitor<T> visitor) { return visitor.visit(this); } }
record Pentagon(double s) implements Shape { public <T> T accept(ShapeVisitor<T> visitor) { return visitor.visit(this); } }
class AreaCalculator implements ShapeVisitor<Double> { public Double visit(Circle circle) { return PI * circle.r() * circle.r(); } public Double visit(Rectangle rectangle) { return rectangle.w() * rectangle.h(); } public Double visit(Triangle tri) { double s = (tri.s1() + tri.s2() + tri.s3()) / 2; return sqrt(s * (s - tri.s1()) * (s - tri.s2())* (s - tri.s3())); } public Double visit(Pentagon p) { return (0.25) * sqrt(5 * (5 + 2 * sqrt(5))) * p.s() * p.s(); } }
class PerimeterCalculator implements ShapeVisitor<Double> { public Double visit(Circle circle) { return 2 * PI * circle.r(); } public Double visit(Rectangle rectangle) { return 2 * (rectangle.w() + rectangle.h()); } public Double visit(Triangle triangle) { return triangle.s1() + triangle.s2() + triangle.s3(); } public Double visit(Pentagon pentagon) { return 5 * pentagon.side(); } }
class InfoVisitor implements ShapeVisitor<String> { public String visit(Circle circle) { return "Circle with radius: %.2f, area: %.2f, perimeter: %.2f" .formatted(circle.r(), new AreaCalculator().visit(circle), new PerimeterCalculator().visit(circle)); } public String visit(Rectangle rect) { return "Rectangle with width: %.2f , height: %.2f, area: %.2f, perimeter: %.2f" .formatted(rect.w(), rect.h(), new AreaCalculator().visit(rect), new PerimeterCalculator().visit(rect)); } public String visit(Triangle tri) { return "Triangle with sides: %.2f, %.2f, %.2f, area: %.2f, perimeter: %.2f" .formatted(tri.s1(), tri.s2(), tri.s3(), new AreaCalculator().visit(tri), new PerimeterCalculator().visit(tri)); } public String visit(Pentagon pentagon) { return "Pentagon with side: %.2f, area: %.2f, perimeter: %.2f" .formatted(pent.side(), new AreaCalculator().visit(pent), new PerimeterCalculator().visit(pent)); } }
class Shapes { public static void main(String[] args) { List<Shape> shapes = List.of(new Circle(5), new Triangle(3, 3, 3), new Rectangle(3, 5), new Pentagon(5.6)); InfoVisitor infoVisitor = new InfoVisitor(); System.out.println("\nShapes:"); shapes.stream().map(s -> s.accept(infoVisitor)).forEach(System.out::println); } }
Shapes: [Circle[radius=5.0], Triangle[side1=3.0, side2=3.0, side3=3.0], Rectangle[width=3.0, height=5.0], Pentagon[side=5.6]] Circle with radius: 5.00, area: 78.54, perimeter: 31.42 Triangle with sides: 3.00, 3.00, 3.00, area: 3.90, perimeter: 9.00 Rectangle with width: 3.00 , height: 5.00, area: 15.00, perimeter: 16.00 Pentagon with side: 5.60, area: 53.95, perimeter: 28.00
sealed interface Shape
permits Circle, Rectangle, Triangle, Pentagon {}
record Circle(double r) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
record Triangle(double s1, double s2, double s3) implements Shape {}
record Pentagon(double s) implements Shape {}
static double area(Shape shape) {
return switch (shape) {
case Circle(var r) -> PI * r * r;
case Rectangle(var w, var h) -> w * h;
case Triangle(var s1, var s2, var s3) -> {
double s = (s1 + s2 + s3) / 2;
yield sqrt(s * (s - s1) * (s - s2) * (s - s3));}
case Pentagon(var s) -> (0.25) * sqrt(5 * (5 + 2 * sqrt(5))) * s * s;
};
}
static double perimeter(Shape shape) {
return switch (shape) {
case Circle(var r) -> 2 * PI * r;
case Rectangle(var w, var h) -> 2 * (w + h);
case Triangle(var s1, var s2, var s3) -> s1 + s2 + s3;
case Pentagon(var s) -> 5 * s;
};
}
static String info(Shape shape) {
return switch (shape) {
case Circle c ->
"Circle with radius: %.2f, area: %.2f, perimeter: %.2f"
.formatted(c.r(), area(c), perimeter(c));
case Rectangle r ->
"Rectangle with width: %.2f , height: %.2f, area: %.2f, perimeter: %.2f"
.formatted(r.w(), r.h(), area(r), perimeter(r));
case Triangle t ->
"Triangle with sides: %.2f, %.2f, %.2f, area: %.2f, perimeter: %.2f"
.formatted(t.s1(), t.s2(), t.s3(), area(t), perimeter(t));
case Pentagon p ->
"Pentagon with side: %.2f, area: %.2f, perimeter: %.2f"
.formatted(p.s(), area(p), perimeter(p));
};