improved algorithm

types can now modify the whole match through a callback, instead of just
wrapping it