polysemy-research / polysemy-zoo

:monkey::panda_face: Experimental, user-contributed effects and interpreters for polysemy
BSD 3-Clause "New" or "Revised" License
70 stars 21 forks source link

Redis interpretations #33

Closed isovector closed 5 years ago

ocharles commented 5 years ago

I wonder if we should have some kind of Embed type, like Lift, but with some kind of run function that lets you run to any MonadIO and automatically lift that back into Sem:

runEmbed :: Member (Lift IO) es => Sem (Embed : es) a -> Sem es a

I say that because this PR requires me to run to the Redis monad, but what if I have a different base?

isovector commented 5 years ago

@ocharles I don't understand. Mind fleshing out that idea a little further?

ocharles commented 5 years ago

Sorry, I serves me right for leaving comments late at night!

Let's say I have some kind of app where I already have some MyApp monad. This carries with it a Redis connection, and a PostgreSQL connection. I want to lay on polysemy for some stuff, in particular the KV store using Redis, but also my own custom SQL effect. Currently, this PR gives me:

runKVStoreInRedis :: Member (Lift R.Redis) r => Sem (KVStore k v ': r) a -> Sem r a

But I may also have written my own

runSQL :: Member (Lift MyApp) r => Sem (SQL ': r) a -> Sem r a

Then I can't compose these together, because the only thing I can do with Lift is runM which needs exactly one Lift.

My suggestion is a more general Embed effect instead of lift, that when ran would let you apply a natural transformation back into Lift. So in this can I could run the R.Redis embedding with R.Redis ~> MyApp natural transformatino.

Or am I missing something?

isovector commented 5 years ago

Then I can't compose these together, because the only thing I can do with Lift is runM which needs exactly one Lift.

This is not true, you can interpret Lifts just like any other effect. This is probably worth exposing in the form runLift :: Member (Lift m2) r => (forall x. m1 x -> m2 x) -> Sem (Lift m1 ': r) a -> Sem r a, which seems like the gist of what you're suggesting?

ocharles commented 5 years ago

Yea exactly. Right now Lift is in an Internal module suggesting it shouldn't be touched