polysemy/polysemy-plugin
Sandy Maguire 7a009f70b6
Let plugin solve stuck type rows + bug fixes in interpreter mode (#245)
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!
2019-10-09 14:07:46 +02:00
..
src/Polysemy Let plugin solve stuck type rows + bug fixes in interpreter mode (#245) 2019-10-09 14:07:46 +02:00
test Let plugin solve stuck type rows + bug fixes in interpreter mode (#245) 2019-10-09 14:07:46 +02:00
.gitignore Release polysemy-plugin-0.2.0.0 2019-05-23 17:06:24 -04:00
ChangeLog.md Release polysemy-plugin-0.2.3.0 2019-09-04 11:19:39 -07:00
LICENSE plugin 2019-04-20 18:31:17 -04:00
package.yaml polysemy-plugin: Reject ununifiable effect candidates early (#221) 2019-09-04 17:11:01 +02:00
polysemy-plugin.cabal Let plugin solve stuck type rows + bug fixes in interpreter mode (#245) 2019-10-09 14:07:46 +02:00
README.md Fix plugin badge 2019-06-26 10:23:06 -04:00
Setup.hs plugin 2019-04-20 18:31:17 -04:00

polysemy-plugin

Build Status Hackage

Dedication

It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong.

Richard Feynman

Overview

A typechecker plugin that can disambiguate "obvious" uses of effects in polysemy.

Example

Consider the following program:

foo :: Member (State Int) r => Sem r ()
foo = put 10

What does this program do? Any human will tell you that it changes the state of the Int to 10, which is clearly what's meant.

Unfortunately, polysemy can't work this out on its own. Its reasoning is "maybe you wanted to change some other State effect which is also a Num, but you just forgot to add a Member constraint for it."

This is obviously insane, but it's the way the cookie crumbles. polysemy-plugin is a typechecker plugin which will disambiguate the above program (and others) so the compiler will do what you want.

Usage

Add the following line to your package configuration:

ghc-options: -fplugin=Polysemy.Plugin

Limitations

The polysemy-plugin will only disambiguate effects if there is exactly one relevant constraint in scope. For example, it will not disambiguate the following program:

bar :: Members '[ State Int
                , State Double
                ] r => Sem r ()
bar = put 10

because it is now unclear whether you're attempting to set the Int or the Double. Instead, you can manually write a type application in this case.

bar :: Members '[ State Int
                , State Double
                ] r => Sem r ()
bar = put @Int 10

Acknowledgments

This plugin is copied almost verbatim from simple-effects.