Streaming libraries and polysemy - Polysemy

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Diamondy4

Is there any\ease way to return conduit\streaming\etc from effect method? It would be better for performance in some cases (like data from file) instead of lists. I tried changing list to conduit, but it results in higher-order effect and I struggle with writing interpreters for it. I also tried to pass stream consumer as FoldM but faced same struggling.

For example i have one effect (returning conduit or with explicit consumer - it would be ok either way).
Result () from conduit for simplicity (can have some meaningful result).

data MyEffectConduit m a where
    MyMethodConduit :: MyEffectConduit m (ConduitT i Int m ())
makeSem ''MyEffectConduit
data MyEffectFold m a where
    MyMethodFold :: FoldM m Int () -> MyEffectFold m ()
makeSem ''MyEffectFold

And I have some working implementation

myMethodFoldSomeImpl :: Members someEffs r => Sem r (Conduit i Int (Sem r) ())
myMethodFoldSomeImpl = ...

or

myMethodFoldSomeImpl' :: Members someEffs r => Conduit i Int (Sem r) ()
myMethodFoldSomeImpl' = ...

Is there any way to interpret it? Polysemy says that I should use interpretH, but it's very confusing.\

interpretMyEffectConduit :: Members someEffs r => InterpreterFor MyEffectConduit r
interpretMyEffectConduit = interpretH \case
    MyMethodConduit -> ???? what's going on here ????

or same with explicit stream elimination with consumer, interpreting MyEffectFold.

I tried to use tactics but often got an error that some effect in r is not found in rInitial.
Very confusing :<

Sandy Maguire

I actually just came to ask the same thing.

Sandy Maguire

After fighting with it for a few days, I'm pretty sure the answer is no. The necessary return type requires contravariance of the monad being run

Sandy Maguire

Or, alternatively, you can force it all inside of the interpreter.... but this doesn't give any sort of desirable streaming behavior.

Torsten Schmits

I use Final in one dedicated interpreter and pass all effects to one constructor from the call site. Alternatively, you can use Final all over the place and lower each action individually.

Maybe we could provide an instance of MonadTransControl with Love's new core implementation that's still waiting in a branch?