diff --git a/slides.md b/slides.md index 20fe91a..8dccaa0 100644 --- a/slides.md +++ b/slides.md @@ -500,6 +500,85 @@ --- +# ADTs: DSLs + +```java +sealed interface Expr { + record Val(int value) implements Expr {} + record Sum(Expr left, Expr right) implements Expr {} + record Diff(Expr left, Expr right) implements Expr {} + record Times(Expr left, Expr right) implements Expr {} +} +``` + +* ADTs son muy útiles para definir DSLs + +--- + +# ADTs: DSLs + +```java +sealed interface Expr { + default int evaluate() { + return switch (this) { + case Val(var value) -> value; + case Sum(var left, var right) -> left.evaluate() + right.evaluate(); + case Diff(var left, var right) -> left.evaluate() - right.evaluate(); + case Times(var left, var right) -> left.evaluate() * right.evaluate(); + }; + } +} +``` + +--- + +# ADTs: DSLs + +```java +sealed interface Expr { + default String asString() { + return switch (this) { + case Val(var value) -> String.valueOf(value); + case Sum(var left, var right) -> "(" + left.asString() + "+" + right.asString() + ")"; + case Diff(var left, var right) -> "(" + left.asString() + "-" + right.asString() + ")"; + case Times(var left, var right) -> "(" + left.asString() + "*" + right.asString() + ")"; + }; + } +} +``` + +--- + +# ADTs: DSLs + +```java +sealed interface Expr { + default void print() { + System.out.println(asString() + "=" + evaluate()); + } +} +``` + +--- + +# ADTs: DSLs + +```java +sealed interface Expr { + static void main() { + sum(val(1), val(2)).print(); + times(diff(val(10), val(8)), val(2)).print(); + } +} +``` + +``` +(1+2)=3 +((10-8)*2)=4 +``` + +--- + # ADTs: Errores ```java @@ -530,6 +609,40 @@ ``` --- +# ADTs: Errores + +```java +@PostMapping("/movies") +public ResponseEntity create(@RequestBody Movie movie) { + var result = repository.create(movie); + return switch (result) { + case MovieCreated(var id) -> ResponseEntity.ok(id); + case MovieError e -> ResponseEntity.of(toProblem(e)).build(); + }; +} +``` + +--- +# ADTs: Errores + +```java +static ProblemDetail toProblem(CreateMovieResponse.MovieError error) { + var detail = switch (error) { + case DuplicatedMovie(int id) -> "duplicated movie with id: " + id; + case InvalidDuration(var duration) -> "invalid duration: " + duration; + case InvalidYear(var duration) -> "invalid year: " + duration; + case InvalidStars(var stars) -> "invalid stars: " + stars; + case EmptyTitle() -> "title cannot be empty"; + case EmptyDirector() -> "director cannot be empty"; + case EmptyCast() -> "cast cannot be empty"; + case DuplicatedActor(var actor) -> "duplicated actor: " + actor; + }; + + return ProblemDetail.forStatusAndDetail(BAD_REQUEST, detail); +} +``` + +--- # ADTs: Either @@ -539,6 +652,16 @@ } ``` +```java +@PostMapping("/movies") +public ResponseEntity create(@RequestBody Movie movie) { + var result = repository.create(movie); + return result.fold( + error -> ResponseEntity.of(toProblem(error)).build(), + ResponseEntity::ok); +} +``` + --- # Próximamente :watch: diff --git a/snippets/Expr.java b/snippets/Expr.java index 0321856..0b9aabe 100644 --- a/snippets/Expr.java +++ b/snippets/Expr.java @@ -1,30 +1,34 @@ sealed interface Expr { - record Lit(int value) implements Expr {} + record Val(int value) implements Expr {} record Sum(Expr left, Expr right) implements Expr {} record Diff(Expr left, Expr right) implements Expr {} record Times(Expr left, Expr right) implements Expr {} default int evaluate() { return switch (this) { - case Lit(var value) -> value; + case Val(var value) -> value; case Sum(var left, var right) -> left.evaluate() + right.evaluate(); case Diff(var left, var right) -> left.evaluate() - right.evaluate(); case Times(var left, var right) -> left.evaluate() * right.evaluate(); }; } - - default String print() { + + default String asString() { return switch (this) { - case Lit(var value) -> String.valueOf(value); - case Sum(var left, var right) -> "(" + left.print() + "+" + right.print() + ")"; - case Diff(var left, var right) -> "(" + left.print() + "-" + right.print() + ")"; - case Times(var left, var right) -> "(" + left.print() + "*" + right.print() + ")"; + case Val(var value) -> String.valueOf(value); + case Sum(var left, var right) -> "(" + left.asString() + "+" + right.asString() + ")"; + case Diff(var left, var right) -> "(" + left.asString() + "-" + right.asString() + ")"; + case Times(var left, var right) -> "(" + left.asString() + "*" + right.asString() + ")"; }; } - static Expr lit(int value) { - return new Lit(value); + default void print() { + System.out.println(asString() + "=" + evaluate()); + } + + static Expr val(int value) { + return new Val(value); } static Expr sum(Expr left, Expr right) { @@ -40,7 +44,7 @@ } static void main() { - assert sum(lit(1), lit(2)).evaluate() == 3; // 1 + 2 = 3 - assert times(diff(lit(10), lit(8)), lit(2)).evaluate() == 4; // (10 - 8) * 2 = 4 + sum(val(1), val(2)).print(); + times(diff(val(10), val(8)), val(2)).print(); } }