re-xyr / cleff

Fast and concise extensible effects

Home Page:https://hackage.haskell.org/package/cleff

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inference helper class

ramirez7 opened this issue · comments

I just wanted to share some code I'm using to help with type inference for higher-kinded effects.

cleff-plugin wasn't an option for me because I am x-compiling. See this GHC ticket.

The effects I was using were unique for my effect stack anyways, so I was able to use a helper type class with a fundep to get GHC to figure out the type parameter that the plugin would normally help with. I added a little more stuff to guarantee the effect is only used once (just like mtl fundeps ensure in that world).

Here's the code! https://gist.github.com/ramirez7/fab0ba053f27b73c2a50bafa69c26be4

theAsks
  :: forall r a es
   . The Reader es r
  => Reader r :> es
  => (r -> a)
  -> Eff es r
theAsks f = f <$> ask @r

^ theAsk will never run into inference issues even if the function you pass to it is highly parametric (e.g. optics and labels and such. Like theAsks $ view #player % #speed). The only downside is you can't have multiple Readers.


PS I love the library and it's working great for me so far! I'm using it for gamedev and it's really cleaned up my code compared to mtl style. And my small stuff is still humming at 60fps with plenty of headroom.

PPS I also have an alternative that uses implicit Proxy params in a similar way to nudge inference. That was mostly for fun, but it was cool nonetheless.

I'm glad that cleff works well for you! I had a look at your The class, it was neat. It seems that to use theAsk, the call site needs to have both The Reader es r and Reader r :> es - is it possible to make the latter a superclass of the former, i.e. class f e :> es => The f es e, so that only The is needed?

I was able to make it a superclass and it Just Worked! Very cool - I've never used superclasses for type-level computations like that. Thank for the code review 🤠

Closing for now - if you have any further suggestions/questions let me know!

This is what the ImplicitParam approach looks like fwiw https://gist.github.com/ramirez7/60aa92aa8e0e1f368e0e6bef69bc2591