fused-effects
fused-effects copied to clipboard
Enable type-level distinctions between operations that thread state and those that don’t.
We removed the Resource effect in #268 because of its unlawful interactions with the State
effect. This was the right move, but it is also a bummer, because the Resource
effect is extremely useful.
What would be ideal is a system like polysemy
’s Tactics
module, which used in concert with Resource
and the withLowerToIO
system provided by their forklift implementation. Failing that, it would be ideal to have some type-level mechanism that rejects calls to functions like get
and put
inside a finally block:
finally :: (Has Resource sig, Carrier sig m, IsStatelessIn n m)
=> m a
-> n a
-> m a
where this hypothetical IsStatelessIn
construct is fulfilled by Reader
but not by State
. Or something. Either approach would be acceptable to me; that would enable us to deprecate fused-effects-exceptions
and welcome Resource
back into the fold.
I was following along with some of the polysemy
work on Tactics
and Strategy
and remembered some threads that may be useful if y'all end up going down that route:
@KingoftheHomeless discusses the Final
and Lift'
effects for embedding higher order effects
@KingoftheHomeless PR's these effects, along with the Strategy
environment for making this higher-order effect weaving easier
Strategy
and Final
have since been merged into polysemy
, but most of the history and discussion is in polysemy-zoo
IIRC.
Notably, asyncToIOFinal
(which uses Strategy
) obviates the need for all the Forklift
machinery and so avoids the additional thread + polling machinery.
I believe #296 gives us this capability.
296 will close this, yes.
So it looks like you said #296 would give us this capability but that PR was ultimately closed. I, like many others, are coming to this for the desire to be able to asyncify things that are effectively Identity wrappers. All the issues talking about this are dead-ended in some way. What's the state of the art knowledge on how to deal with this?
EDIT: the desire is to retain the ability to have multiple interpretations, none of them need to have state in the context functor though
@ProofOfKeags At the risk of sounding full of myself, the state of the art on this would be the approach taken by my newly released library: in-other-words
. One thing the approach does is that an interpreter may introduce constraints that restrict what other interpreters may be used together with it. This gives you what you're looking for: you can have an effect for concurrency, since its interpreter can place restrictions on what other interpreters you may use to guarantee that it's able to unlift to IO
.
@KingoftheHomeless Cool that you were able to solve this. Can't say I'm a fan of trying to switch effect systems as a result of this, but I may still attempt to do so at some point. I was hoping I'd be able to patch fused-effects or restrict myself to some subset of the library in order to do be able to use async effects.
It’s possible we could take the same approach in fused-effects
(haven’t looked into it yet), but failing that, it’s also possible to do what I’m doing in starlight
& isometry
and just… drop any state changes happening on the background thread.
That’s not ideal, and it’s regrettably silent, but it does allow for sensible use if you keep that in mind: basically, you get to make and observe any sort of local state changes you want in the forked thread, so long as you remember that they’re not going to be magically synchronized back to the forking thread.
Further, you can also use this sort of thing to set up some sort of synchronization mechanism to transport state changes across threads; I’m doing that in those projects, too.
So all is not lost!
I think this is definitely superior to straight up not having a polymorphic async effect. I think a big warning on the tin that says that the pure construction of state/writer won't propagate over async effects is something that most people would have the capacity to understand.
In fused-effects-exceptions
there’s a carrier for State
that uses an IORef
and thus doesn’t lose information. We could add one for Writer
as well.