refactored gates into a single struct type that takes a fn arg determining the operation