
Steven Watanabe wrote:
The thing is, in most cases, the tuple type is chosen by Yap, not by the user. Most of the time, users don't actually need to care what the tuple type is, either.
...
struct a_transform { template<class T> auto operator()(terminal_tag, T&&t); // ... };
Right. I'd guess that tag matching is a later addition, because it only works for simple cases. You can't do auto operator()(any_expression_tag, T&&... t); because there's no way to match a tag, they are just classes, unrelated to anything (and do not even appear in the reference.) One would expect instead of struct plus_tag {}; something rather like template<expr_kind kind> struct expression_tag {}; using plus_tag = expression_tag<expr_kind::plus>; and now f.ex. template<expr_kind kind, class... T> auto get_arity::operator()(expression_tag<kind>, T const&... t) const { return std::max( { yap::transform(t, get_arity{})... } ); }