Polysemy: Strategies bindingGautier DI FOLCO January 22, 2023 [Haskell] #haskell #polysemy #design #effects systems
In a previous log, we introduced
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
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
= interpretFinal @IO $ \case Bracket alloc dealloc use -> do alloc' <- runS alloc dealloc' <- bindS dealloc use' <- bindS use return $ Exception.bracket alloc' dealloc' use' resourceToIOFinal
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:
= interpretFinal @IO $ \case BindE f g -> do fa <- runS f ff <- bindS g pure $ fa >>= ff interpretBindFinal
See the full the code here and here.