-
-
Save tinco/4105864 to your computer and use it in GitHub Desktop.
Concurrent prime sieve translated from Go (http://play.golang.org/p/9U22NfrXeq)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Compile with `ghc -threaded -with-rtsopts=-N concurrent_sieve.hs` | |
import Control.Concurrent | |
import Control.Monad | |
import System.Environment | |
-- Map over [2..] (2 until infinity), putting the value in mOut. The putting operation will block until | |
-- mOut is empty. mOut will become empty when some other thread executes takeMVar (getting its value). | |
generate :: MVar Int -> IO () | |
generate mOut = mapM_ (putMVar mOut) [2..] | |
-- Take a value from mIn, divide it by a prime, if the remainder is not 0, put the value in mOut. | |
primeFilter :: MVar Int -> MVar Int -> Int -> IO () | |
primeFilter mIn mOut prime = forever $ do | |
i <- takeMVar mIn | |
when (i `mod` prime /= 0) (putMVar mOut i) | |
-- Take the first commandline argument and call it numArg. | |
-- Create a new mVar and call it mIn and spawn a thread that runs generate on mIn. | |
-- Read numArg as an integer value, and run newEmptyMVar that amount of times, | |
-- calling the result out. | |
-- Fold over the elements of out, with the function linkFilter, having mIn as the first value. | |
main = do numArg:_ <- getArgs | |
mIn <- newEmptyMVar | |
forkIO $ generate mIn | |
out <- replicateM (read numArg) newEmptyMVar | |
foldM_ linkFilter mIn out | |
-- Take a value from mIn, and call it prime. Then show that prime. Make a new thread that | |
-- runs primeFilter with mIn, mOut and the prime. When this function is used as a fold | |
-- function, mOut becomes the mIn of the next iteration. | |
linkFilter :: MVar Int -> MVar Int -> IO (MVar Int) | |
linkFilter mIn mOut = do prime <- takeMVar mIn | |
putStrLn $ show prime | |
forkIO $ primeFilter mIn mOut prime | |
return mOut |
Woops, absolutely right, that's what I get for making changes without compiling ;)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think you need a
$
betweenforever
anddo
on line 15 or it won't parse correctly.Good comments though. :)