Description
I really want to like freer-simple
, but I can't until it infers at least as well as idiomatic mtl usage. The big problem at the moment is Member
:
class FindElem eff effs => Member (eff :: * -> *) effs
This multi-parameter type class infers miserably because there is no connection between the parameters. However, we can do better! Ignoring FindElem
for now, this has much better inference, at the cost of: a. limiting you to a single type of effect and b. Adding a parameter to effect definitions:
class Member ( eff :: k -> * -> * ) config effs | effs eff -> config
That is, if I know the set of effects and a particular effect, I can tell you the "configuration" of that effect. Configured or parameterized effects are polymorphic effects such Reader
, State
, etc. This encoding means
Member Reader r effs
is like
MonadReader r m
This has the same "drawbacks" as functional dependencies in mtl
, but I believe those drawbacks are significantly overblown. The good news is that as effects are first class in freer-simple
, it's pretty trivial to just newtype
Reader
for example to have it occur twice (at different types) in eff
.
The complication to the kind of eff
can probably be worked around with
data Mono (eff :: * -> *) (config :: ()) a where
Mono :: eff a -> Mono '() a
or something.
What do you think? Happy to throw up a PR if you want to see how it looks in practice. I'm using this in a private extensible effects like library to much success.