Turns out I don't need semigroups