@@ -6,38 +6,27 @@ module Main where
6
6
7
7
import Control.Concurrent.MVar (MVar , newEmptyMVar , readMVar , takeMVar , putMVar )
8
8
import 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 )
12
12
13
13
input1 = [ 1 , 1 , 1 , 2 ]
14
14
input2 = [ 2 , 3 , 4 , 4 ]
15
15
16
16
worker :: [Int ] -> MVar (Maybe Int ) -> IO ()
17
17
worker [] 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
21
19
22
20
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
21
+ merge slots output = traverse readMVar slots >>= \ values ->
22
+ case filter (isJust . snd ) $ zip [0 .. ] values of
28
23
[] -> 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])
35
27
36
28
main :: IO ()
37
29
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
30
+ slots <- sequenceA $ replicate 2 newEmptyMVar
31
+ traverse (forkIO . uncurry worker) $ zip [input1, input2] slots
32
+ print =<< merge slots []
0 commit comments