Visitable and visitor protocols

Thanks to Swift and its expressive generics, it is possible to abstract the visitor pattern through a series of protocols:

protocol Visitor {
func visit<T>(element: T) where T:Visitable
}

A Visitor is an object that can traverse Visitable elements. It implements a single method, which is generic:

protocol Visitable {
func accept(visitor: Visitor)
}

Visitable objects can be traversed by a Visitor. Here we don't use the generics, as they're not needed:

// Default implementation for our visitable nodes
extension Visitable {
func accept(visitor: Visitor) {
visitor.visit(element: self)
}
}

For the sake of simplicity, and because this is the general use case, we'll want the Visitable objects simply to call visit on the Visitor when they're being visited:

// Convenience on Array for visitables
extension Array: Visitable where Element: Visitable {
func accept(visitor: Visitor) {
visitor.visit(element: self)
forEach {
visitor.visit(element: $0)
}
}
}

It is possible to extend arrays of Visitable objects to be Visitable themselves. This may also help with default implementations.

With this base layer of protocols defined, it is possible to retrofit our examples for visitation.