Skip to content

Commit 740e81c

Browse files
committed
concurrent-merge: init
1 parent 862205b commit 740e81c

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

concurrent-merge/Main.hs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#! /usr/bin/env nix-shell
2+
#! nix-shell -i runhaskell
3+
#! nix-shell -p "haskellPackages.ghcWithPackages (p: [ p.base ])"
4+
5+
module Main where
6+
7+
import Control.Concurrent.MVar (MVar, newEmptyMVar, readMVar, takeMVar, putMVar)
8+
import Control.Concurrent (forkIO)
9+
import Data.Maybe (isJust)
10+
import Data.List (sortOn)
11+
12+
13+
input1 = [ 1, 1, 1, 2 ]
14+
input2 = [ 2, 3, 4, 4 ]
15+
16+
worker :: [Int] -> MVar (Maybe Int) -> IO ()
17+
worker [] slot = putMVar slot Nothing
18+
worker (x:xs) slot = do
19+
putMVar slot (Just x)
20+
worker xs slot
21+
22+
merge :: [MVar (Maybe Int)] -> [Int] -> IO [Int]
23+
merge slots output = do
24+
values <- traverse readMVar slots
25+
let values' = zip [0..] values
26+
let filled = filter (\(_, i) -> isJust i) values'
27+
case filled of
28+
[] -> return output
29+
_ -> do
30+
let sorted = sortOn (\(_, Just i) -> i) filled
31+
let (idx, Just el) = head sorted
32+
let output' = output ++ [el]
33+
takeMVar (slots !! idx)
34+
merge slots output'
35+
36+
main :: IO ()
37+
main = do
38+
slot1 <- newEmptyMVar
39+
slot2 <- newEmptyMVar
40+
forkIO $ worker input1 slot1
41+
forkIO $ worker input2 slot2
42+
result <- merge [slot1, slot2] []
43+
print result

0 commit comments

Comments
 (0)