@@ -6,38 +6,27 @@ module Main where
66
77import Control.Concurrent.MVar (MVar , newEmptyMVar , readMVar , takeMVar , putMVar )
88import Control.Concurrent (forkIO )
9- import Data.Maybe (isJust )
10- import Data.List (sortOn )
11-
9+ import Data.Maybe (isJust , fromJust )
10+ import Data.List (minimumBy )
11+ import Data.Ord ( comparing )
1212
1313input1 = [ 1 , 1 , 1 , 2 ]
1414input2 = [ 2 , 3 , 4 , 4 ]
1515
1616worker :: [Int ] -> MVar (Maybe Int ) -> IO ()
1717worker [] slot = putMVar slot Nothing
18- worker (x: xs) slot = do
19- putMVar slot (Just x)
20- worker xs slot
18+ worker (x: xs) slot = putMVar slot (Just x) >> worker xs slot
2119
2220merge :: [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
21+ merge slots output = traverse readMVar slots >>= \ values ->
22+ case filter (isJust . snd ) $ zip [0 .. ] values of
2823 [] -> 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'
24+ ls -> let
25+ (ix, Just el) = minimumBy (comparing (fromJust . snd )) ls
26+ in takeMVar (slots !! ix) >> merge slots (output ++ [el])
3527
3628main :: IO ()
3729main = 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
30+ slots <- sequenceA $ replicate 2 newEmptyMVar
31+ traverse (forkIO . uncurry worker) $ zip [input1, input2] slots
32+ print =<< merge slots []
0 commit comments