When access to term members inside an ADT is exclusively done via pattern matching or combinators, having to name members is tedious and useless. For instance:
enum Tree[+T]:
case B(left: Tree[T], value: T, right: Tree[T])
case E
def fold[A](onEmpty: A, onBranch: (A, T, A) => A): A =
def go(x: Tree[T]): TailRec[A] = x match
case B(l, v, r) => tailcall:
for l <- go(l)
r <- go(r)
yield onBranch(l, v, r)
case E => done(onEmpty)
go(this).result
The names left
, value
and right
in Tree.B
are never used. Would it be possible to synthesise names at compile-time and let developers write:
enum Tree[+T]:
case B(Tree[T], T, Tree[T])
case E
? We found that our datatypes fall into two categories: domain objects where names are relevant, and eDSL which are often (co-)recursive ADTs and come with interpreters/compilers, where names are irrelevant.