interface Visitor<A, R> {
R visitAdd(Add<A> add);
R visitMul(Mul<A> mul);
R visitNum(Num<A> num);
}Но это правда на Java, а в C# например он не нужен, т.к. в нём уже есть взрослый встроенный pattern matching.
Кстати, не помню уже чей картинка, автору респект, кто реализовывал Software Transactional Memory на плюсах и std через free monads, и там visitor тоже являлся в конечном итоге.
