Admittedly non-illuminating, and maybe even misleading, musings:<p>I like to think of free monads and related constructions as dependency injection &quot;turned inside out&quot;. With dependency injection, you configure a foozle in various ways, and then the foozle controls how and when to use the injected components. The foozle is on the outside; the dependencies, once injected, are on the inside.<p>With a free monad, the foozle (the &quot;logic&quot; of the application) is on the inside, and an outside interpreter is the one that services all the &quot;effect requests&quot;. The foozle is &quot;run&quot; by the interpreter.<p>That&#x27;s the basic idea. Then there are practical concerns of how to make it fast enough, of how to be able to handle different combinations of effects (environment reads, state, io requests...) without requiring boilerplate, and so on.