Polysemy: Strategies binding
In a previous log, we introduced liftS
and runS
which helps running higher-order effects in the interpretation Monad.
However, you sometime have effects with multiple higher-order effects needing to be bound, sur as Resource
:
data Resource m a where
Bracket :: m a -> (a -> m c) -> (a -> m b) -> Resource m b
In order to have a working interpreter we have to use bindS
:
resourceToIOFinal =
interpretFinal @IO $
\case
Bracket alloc dealloc use -> do
alloc' <- runS alloc
dealloc' <- bindS dealloc
use' <- bindS use
return $ Exception.bracket alloc' dealloc' use'
bindS
is pretty straightforward:
With a simpler effect:
data BindE (m :: Type -> Type) a where
BindE :: m a -> (a -> m b) -> BindE m b
makeSem ''BindE
We see that a simple bind does the trick:
interpretBindFinal =
interpretFinal @IO $
\case
BindE f g -> do
fa <- runS f
ff <- bindS g
pure $ fa >>= ff