Use GADTs to try to ensure that we always call register functions