Skip to content

Instantly share code, notes, and snippets.

@tallpeak
Created October 23, 2018 21:38
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 tallpeak/f832af9ed92395de3b60fce6a64fd992 to your computer and use it in GitHub Desktop.
Save tallpeak/f832af9ed92395de3b60fce6a64fd992 to your computer and use it in GitHub Desktop.
-- based on
-- https://stackoverflow.com/questions/4522387/how-can-i-emulate-gos-channels-with-haskell
-- but this version encodes end-of-stream on the communication channel, as a Nothing
-- I could not get Intero or ghc to accept a type-annotation for the helper function,
-- even using the exact inferred type from Intero.
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 (Maybe a) -> (a -> IO b) -> IO [b]
forRange ch fn = helper fn [] where
-- helper :: (a -> IO b) -> [b] -> IO [b]
helper fn acc = do
jv <- readQ ch
case jv of
Nothing -> return $ reverse acc
Just v -> do
b <- fn v
helper fn (b : acc)
generate :: (Num a, Enum a) => TChan (Maybe a) -> IO ()
generate ch = do
forM_ [1..9999] (\x -> writeQ ch (Just x))
writeQ ch Nothing -- EOF value
process :: TChan (Maybe Int) -> IO ()
process c = do
forRange c (print :: Int -> IO () )
return ()
main :: IO ()
main = do
ch <- atomically $ newTChan
go $ generate ch
process ch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment