Skip to content

Instantly share code, notes, and snippets.

@Agnishom
Created November 4, 2021 18:45
Show Gist options
  • Save Agnishom/7d25cdbda58540fd6791cd037740e0ac to your computer and use it in GitHub Desktop.
Save Agnishom/7d25cdbda58540fd6791cd037740e0ac to your computer and use it in GitHub Desktop.
Visitor Pattern
/** The functional list type defined by IntList := EmptyIntList + ConsIntList(int, IntList) */
abstract class IntList {
/** Visitor hook */
abstract public Object visit(IntListVisitor iv);
/** Adds i to the front of this. */
public ConsIntList cons(int i) { return new ConsIntList(i, this); }
/** Returns the unique empty list. */
public static EmptyIntList empty() { return EmptyIntList.ONLY; }
}
/** Concrete empty list structure containing nothing. */
class EmptyIntList extends IntList {
/** Singleton binding */
public static final EmptyIntList ONLY = new EmptyIntList();
/** Single pattern constructor */
private EmptyIntList() { }
/** Visitor hook */
public Object visit(IntListVisitor v) { return v.forEmptyIntList(this); }
}
/** Concrete non-empty list structure containing an int, called first, and an IntList called rest. */
class ConsIntList extends IntList {
/** Cons node fields */
int first;
IntList rest;
/** Data constructor for ConsIntList */
ConsIntList(int f, IntList r) { first = f; rest = r; }
/** Accessors */
public int first() { return first; }
public IntList rest() { return rest; }
public Object visit(IntListVisitor v) { return v.forConsIntList(this); }
}
/** Visitor interface for the IntList type. */
interface IntListVisitor {
abstract Object forEmptyIntList(EmptyIntList host);
abstract Object forConsIntList(ConsIntList host);
}
/**
IntListVisitor class that implements the length() method on IntLists.
length :: [Int] -> Int
length [] = 0
length xs = 1 + length (tail xs)
*/
class LengthVisitor implements IntListVisitor {
/* Singleton binding for LengthVisior because the method takes no parameters */
public static final LengthVisitor ONLY = new LengthVisitor();
private LengthVisitor() { }
public Object forEmptyIntList(EmptyIntList el) { return 0; }
public Object forConsIntList(ConsIntList cil) { return 1 + (Integer) cil.rest().visit(this); }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment