In scala, this operation frequently not called visitor pattern. In general, functional constructs rather than GOF patterns used for different utility tasks such as working with collection or so, thanks to fancy libraries like cats
or scalaZ
.
There's Functor
which yields you the ability to map over data structures, and also there's Monad
abstraction which adds the creation of data structure and flatMap
operation.
So operation map with resulting type unit will do the same thing as the "visitor".
def map[A,B](tree: BinaryTree[A], f: A => B)
Generic way of implementing map for ADT is the recursion with case exhaustion:
def map[A,B](tree: BinaryTree[A], f: A => B): BinaryTree[B]:=
match tree {
case Leaf(a) => Leaf(f(b))
case Branch(l,r) => Branch(map(l,f), map(r,f))
}
Exact "visitor" thing you asking for could be done with throwing of return value.
and you can also add some stack safety, turining this to tail recursion, like described in this question:
How to make tree mapping tail-recursive?
You can also create instances for cats type classes to use cats syntax and abstract over this particular data structure.