You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been playing around with Polysemy recently, and have had some reasonable success with first order interpreters--they really deliver on "write the code the way you wish you could."
I recently tried creating some higher-order interpreters and found it (maybe unsurprisingly) much more challenging. Should these even be really expected within application code, or are these really reserved for things like Resource and Error?
I've started to get my head around the types, but I seems like certain cases with additional actions from constraints are especially challenging. runT and bindT work together to allow chaining the functor through their computations, but if you try to use an effect not in a parameter, the arbitrary Functor requirement gets a bit awkward. In certain cases it seems like you must inspect the state or you end up stuck.
My thought was, that if the Functor was instead Traversable, you could use that to "upgrade" the action in the same way that you use bindT to upgrade the action in the parameter. As an example:
higher = (Member Other r) => Sem (Higher ': r) a -> Sem r a
higher = interpretH \case
Higher paramA paramB -> do
paramA' <- runT paramA
a <- paramA'
paramB' <- bindT paramB'
b <- paramB'
traverse other b
This essentially lets us perform the other action inside the (now Traversable) Functor, but then flip the contexts to end up with the correct type. Ultimately, we're saved from otherwise having to inspect the state.
Is Traversable a reasonable constraint to get the ergonomics here? What actual Functors are used under the hood? I was assuming that while Maybe is used for inspecting, it's not actually ever used as f.
Also, if I'm simply thinking about this problem incorrectly, I'd much appreciate a push in the correct direction. Thanks!
The text was updated successfully, but these errors were encountered:
I've been playing around with Polysemy recently, and have had some reasonable success with first order interpreters--they really deliver on "write the code the way you wish you could."
I recently tried creating some higher-order interpreters and found it (maybe unsurprisingly) much more challenging. Should these even be really expected within application code, or are these really reserved for things like Resource and Error?
I've started to get my head around the types, but I seems like certain cases with additional actions from constraints are especially challenging.
runT
andbindT
work together to allow chaining the functor through their computations, but if you try to use an effect not in a parameter, the arbitrary Functor requirement gets a bit awkward. In certain cases it seems like you must inspect the state or you end up stuck.My thought was, that if the Functor was instead Traversable, you could use that to "upgrade" the action in the same way that you use
bindT
to upgrade the action in the parameter. As an example:This essentially lets us perform the
other
action inside the (now Traversable) Functor, but then flip the contexts to end up with the correct type. Ultimately, we're saved from otherwise having to inspect the state.Is Traversable a reasonable constraint to get the ergonomics here? What actual Functors are used under the hood? I was assuming that while Maybe is used for inspecting, it's not actually ever used as
f
.Also, if I'm simply thinking about this problem incorrectly, I'd much appreciate a push in the correct direction. Thanks!
The text was updated successfully, but these errors were encountered: