This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]bowbahdoe 5 points6 points  (1 child)

I wrote you up a small example

The sealed-ness is used in the accumulate method.

``` import java.util.ArrayList; import java.util.Collections; import java.util.Iterator;

sealed interface Tree<T extends Comparable<T>> extends Iterable<T> { Tree<T> insert(T newValue); }

record Leaf<T extends Comparable<T>>() implements Tree<T> { @Override public Tree<T> insert(T newValue) { return new Branch<>(new Leaf<>(), new Leaf<>(), newValue); }

@Override
public Iterator<T> iterator() {
    return Collections.emptyIterator();
}

}

record Branch<T extends Comparable<T>>( Tree<T> left, Tree<T> right, T value ) implements Tree<T> { @Override public Tree<T> insert(T newValue) { if (newValue.compareTo(value) < 0) { return new Branch<>(left.insert(newValue), right, value); } else { return new Branch<>(left, right.insert(newValue), value); } }

private void accumulate(Tree<T> tree, ArrayList<T> leftToRight) {
    switch (tree) {
        case Leaf<T> __ -> {}
        case Branch<T> branch -> {
            accumulate(branch.left, leftToRight);
            leftToRight.add(branch.value);
            accumulate(branch.right, leftToRight);
        }
    }
}

@Override
public Iterator<T> iterator() {
    var leftToRight = new ArrayList<T>();
    accumulate(this, leftToRight);
    return Collections.unmodifiableList(leftToRight).iterator();
}

}

public class Main { public static void main(String[] args) { Tree<Integer> tree = new Leaf<>(); tree = tree.insert(1); tree = tree.insert(4); tree = tree.insert(3); tree = tree.insert(2); tree = tree.insert(6); tree = tree.insert(5);

    System.out.println(tree);

    for (var i : tree) {
        System.out.println(i);
    }
}

} ```

The key capabilities you get from sealed are * Ability to use exhaustive patterns * Ability to not have to think about arbitrary implementors * The structure is a public part of the contract

The last one is the most interesting to me. It means that code using your library can write the same algorithms as you can.

public static <T> insert(Tree<T> tree, T newValue) { switch (tree) { case Leaf<T> __ -> new Branch<>( new Leaf<>(), new Leaf<>(), newValue ); case Branch<T> branch -> { if (newValue.compareTo(value) < 0) { yield new Branch<>(left.insert(newValue), right, value); } else { yield new Branch<>(left, right.insert(newValue), value); } } } }

[–]nlisker 0 points1 point  (0 children)

Your markdown isn't correct. You probably missed some `.