Skip to content

Instantly share code, notes, and snippets.

@tallpeak
Created October 23, 2018 21:33
Show Gist options
  • Save tallpeak/8135790efd80584b1ee0e578a6f390d8 to your computer and use it in GitHub Desktop.
Save tallpeak/8135790efd80584b1ee0e578a6f390d8 to your computer and use it in GitHub Desktop.
-- based on
-- https://stackoverflow.com/questions/4522387/how-can-i-emulate-gos-channels-with-haskell
-- switched to TChan
-- still does not work right, because it requires a threadDelay between "generate" and "process",
-- of at least 30 to 3000 microseconds to finish queueing the input,
-- because the channel will be empty if the producer can't keep up with the consumer.
import Control.Monad (forM_)
import Control.Concurrent (forkIO, ThreadId, threadDelay)
import Control.Concurrent.STM.TChan (newTChan, readTChan, writeTChan, isEmptyTChan, TChan)
import GHC.Conc (atomically)
readQ :: TChan a -> IO a
readQ v = atomically $ readTChan v
writeQ :: TChan a -> a -> IO ()
writeQ ch v = atomically $ writeTChan ch v
go :: IO () -> IO ThreadId
go = forkIO
forRange :: TChan a -> (a -> IO b) -> IO [b]
forRange ch fn = helper fn [] where
-- helper :: (a -> IO b) -> [b] -> IO [b]
helper fn acc = do
mt <- atomically $ isEmptyTChan ch
if mt then
return $ reverse acc
else
do
v <- readQ ch
b <- fn v
helper fn (b : acc)
--import Control.Monad
-- generate :: Chan Int -> IO ()
generate ch = do
forM_ [1..9999] (writeQ ch)
--process :: TChan Int -> IO ()
process c = do
forRange c print
return ()
main :: IO ()
main = do
ch <- atomically $ newTChan
go $ generate ch
threadDelay 30 -- 3000+ microseconds would be better
process ch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment