In interpreter mode, the plugin used to see rows like State (Identity a) ': State a ': r, with an action in State a, and then incorrectly unify that thing with the first thing in the list State (Identity a). As a result, we'd ask for Identity a ~ a, which is infinite, and things would go wrong.
Now we instead collect all of the unifications we'd like to do, and only emit the most specific one, as measured by number of type constructors in it. This will now only emit a State (Identity a) ~ State (Identity s), and then unify the state we're looking for, plus the a ~ s that solves the other state action.
But the next problem is that we can't determine IndexOf in the row above, because a is a type variable, and so IndexOf is stuck, even though we know IndexOf that_row (State a) ~ 'S 'Z. So the plugin now also solves "stuck" IndexOfs of that form.
All of this means we can now happily introduce local effects that have type variables, for effects that are already known to be present in the row. And somehow it just works! Amazing!
* Add AtomicState and atomic interpreters for Output/Writer
* Fixed a word in docs, moved test functions around
* Remove runWriterIORef and runWriterTVar
* Fix strictness semantics of State and Writer
* Made tests more rigorous
* Fixed inconsistency between Writer/Output tests
* Add more tests to cover the discrepancy between run and runM
* Use strict fmap to be on the safe side
* Improve semantics of Fixpoint
* Add tests for Fixpoint, update docs
* Made the error test more rigorous
* Added references in the docs for 'runFixpoint'
* Polysemy.Internal: document change in semantics based on order of interpreters
* Polysemy.Internal: use new 'evalState' instead of mapping 'runState' in example
* Polysemy.Internal, DoctestSpec: properly support doctest
* Polysemy.Internal: small corrections
* Move Polysemy.Internal.Lift to Polysemy.Lift.Type
* Add Polysemy.Lift module and runLift interpreter
* Add a Sandy reminder
* Add explicit foralls and split type signature
* Fix import spacing, for there is no "qualified"
* Implement runIO in terms of runLift
* Rename Lift -> Embed
* Replace sendM with embed
* Add a Sandy todo for embed version
* Rename runEmbed and related runEmbedded (from IO)
* runEmbedded -> runEmbeddedInIO
* runEmbed -> runEmbedded
* Update cabal