expanded typeclass boilerplate