Skip to content

Instantly share code, notes, and snippets.

@ChrisPenner
Created October 3, 2020 03:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisPenner/f032e9aa3f7f4c1a5e7eb859587ce9e5 to your computer and use it in GitHub Desktop.
Save ChrisPenner/f032e9aa3f7f4c1a5e7eb859587ce9e5 to your computer and use it in GitHub Desktop.
-- Bind an async to be cancelled when the current computation ends.
bindAsync :: IO a -> ContT r IO ()
bindAsync m = do
ContT $ \cc -> do
withAsync m . const $ cc ()
-- Use bindAsync to auto-cancel the thread when the containing computation finishes
testBoundAsync :: ContT r IO ()
testBoundAsync = do
bindAsync . forever $ print "can you hear me now?"
liftIO $ threadDelay 1000000
-- The "traditional" way to accomplish the same thing
-- Notice the need for nesting.
-- It does however give you explicit control over when the async is cancelled, and gives
-- you access to the result of the async if you need it.
testWithAsync :: IO ()
testWithAsync = do
withAsync (forever $ print "can you hear me now?") $ \handle -> do
liftIO $ threadDelay 1000000
-- This version does NOT bind the thread to its containing context
-- and thus will annoyingly print forever.
testSimpleAsync :: ContT r IO ()
testSimpleAsync = do
liftIO . async . forever $ print "can you hear me now?"
liftIO $ threadDelay 1000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment