Free monads let you take a data type that represents instructions, or (approximately the same) effects that you want to happen, and then have interpreters which understand how to make those effects actually happen.