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
pure
the 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