Skip to content

Instantly share code, notes, and snippets.

@mpellegrini
Created May 9, 2019 19:17
Show Gist options
  • Save mpellegrini/0e2b458fbc150859e20b48da0793c5a9 to your computer and use it in GitHub Desktop.
Save mpellegrini/0e2b458fbc150859e20b48da0793c5a9 to your computer and use it in GitHub Desktop.
Example of Functional Visitor Pattern using Vavr
package com.michaelpellegrini.example.functional;
import io.vavr.Function1;
import io.vavr.collection.List;
import static io.vavr.API.$;
import static io.vavr.API.Case;
import static io.vavr.API.Match;
import static io.vavr.Predicates.instanceOf;
public class FunctionalVisitor {
static class Square {
final double side;
Square(double side) {
this.side = side;
}
}
static class Circle {
final double radius;
Circle(double radius) {
this.radius = radius;
}
}
static class Rectangle {
final double width;
final double height;
Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
}
private static Function1<Object, Double> areaCalculatorVisitor = o ->
Match(o).of(
Case($(instanceOf(Square.class)), s -> s.side * s.side),
Case($(instanceOf(Circle.class)), c -> Math.PI * c.radius * c.radius),
Case($(instanceOf(Rectangle.class)), r -> r.height * r.width)
);
private static Function1<Object, Double> perimeterCalculatorVisitor = o ->
Match(o).of(
Case($(instanceOf(Square.class)), s -> 4 * s.side),
Case($(instanceOf(Circle.class)), c -> 2 * Math.PI * c.radius),
Case($(instanceOf(Rectangle.class)), r -> 2 * r.height + 2 * r.width)
);
public static void main(String[] args) {
List<Object> figures = List.of(new Circle(4), new Square(5), new Rectangle(6, 7));
double totalArea = figures.map(areaCalculatorVisitor).reduce(Double::sum);
System.out.println("Total area = " + totalArea);
double totalPerimeter = figures.map(perimeterCalculatorVisitor).reduce(Double::sum);
System.out.println("Total perimeter = " + totalPerimeter);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment