I did some quick-and-dirty profiling, and these functions made up ~2% of the flamegraph, mostly for when they called through to the type parser; also, it's likely that they'll be called repeatedly with many of the same inputs. Memoizing the functions cuts them to ~1% of the flamegraph.