It’s really nice to see this trick to be used in an effect system, I think it’s way underused.
Maybe something that you might not immediately realize, but this also works outside of bluefin. E.g. if you have IO, you can write a newtype ScopedHandle s = UnsafeScopedHandle {getHandle :: Handle} and a function withScopedHandle :: FilePath -> (forall s. ScopedHandle s -> IO r) -> IO r and you will not be able to escape the handle out of the continuation.
Take this in contrast to the usual ways of preventing something like this, like:
- just using a continuation: make
purethe continuation, here you have your handle - make the continuation return
IO ()instead ofIO r: make anIORef, write the handle to theIORef, here you have your handle