Short answer: you can't do this in a safe way. This is one of the flaws inherent to the Effect Handlers In Scope approach (what I call "the weave abstraction") that polysemy is based upon. The same reason is why polysemy doesn't have a Coroutine effect, and why the continuation effects in polysemy-zoo have very restrictive interpreters. However, the unsafe interaction is specifically that if you try to do this, higher-order actions of effects after MyEff get messed up (the ones that have already been interpreted are fine). So if you, say, have no higher-order effects of interest, you can do this.
The implementation would be messy and ugly and convoluted. But if you really want it, I can cook it up.
importPolysemy-- For evil internal magicimportPolysemy.InternalimportPolysemy.Internal.Union-- From the 'free' packageimportControl.Monad.FreeimportControl.Monad.Free.Church-- BoilerplatecataSem::(a->b)->(Unionr(Semr)b->b)->Semra->bcataSembcsem=runF(runSemsemliftF)bcstackify::Semra->Free(Unionr(Semr))astackify=cataSemPureFreeunstackify::Free(Unionr(Semr))a->Semraunstackifyfm=Sem$\k->foldFreekfmbomb::abomb=error"step/s: Don't use any higher-order effects that are further down the \ \ effect stack than the effect you step through!"-- Here's what you're interested indataStepsemawhereDone::a->StepsemaMore::eza->(a->m(Stepsemb))->StepsembdataStepemawhereFloor::a->StepemaStep::ezx->(x->ma)->Stepemasteps::Sem(e':r)a->Semr(Stepse(Semr)a)steps=cataSem(pure.Done)$\u->casedecompuofRight(Weavinges_ex_)->pure(Moree(ex.(<$s)))Leftg->join$liftSem$hoistbombgstep::Sem(e':r)a->Semr(Stepe(Sem(e':r))a)step=go.stackifywherego(Purea)=pure(Floora)go(Freeu)=casedecompuofRight(Weavinges_ex_)->pure(Stepe(unstackify.ex.(<$s)))Leftg->liftSem(hoistbombg)>>=go
Maybe it's worth adding to polysemy-zoo but that's a pretty big maybe seeing how unsafe it is. Also it's heavily dependant on Sem's internal representation as a free monad.
Hi there! I have a scenario where I want to decompose a Sem computation the following way:
(As there might be
r
effects beforeMyEff
)in order to handle the effect step-wise.
My use case is having a bunch of these effectful programs in a collection, and moving them forward together whenever I have a
b
available.How would I go about doing this with Polysemy?
Short answer: you can't do this in a safe way. This is one of the flaws inherent to the Effect Handlers In Scope approach (what I call "the
weave
abstraction") that polysemy is based upon. The same reason is why polysemy doesn't have aCoroutine
effect, and why the continuation effects inpolysemy-zoo
have very restrictive interpreters.However, the unsafe interaction is specifically that if you try to do this, higher-order actions of effects after
MyEff
get messed up (the ones that have already been interpreted are fine). So if you, say, have no higher-order effects of interest, you can do this.The implementation would be messy and ugly and convoluted. But if you really want it, I can cook it up.
Figured "what the hell" and made it anyway:
Maybe it's worth adding to
polysemy-zoo
but that's a pretty big maybe seeing how unsafe it is. Also it's heavily dependant onSem
's internal representation as a free monad.