Adapted from Peter Fraenkel's lazy functors stuff found here: https://gist.github.com/pnf/5750320