HasChor-0.1.0.1: examples/mergesort/Main.hs
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
module Main where
import Choreography (runChoreography)
import Choreography.Choreo
import Choreography.Location
import Choreography.Network.Http
import Data.Proxy
import Data.Time
import GHC.TypeLits (KnownSymbol)
import System.Environment
divide :: [a] -> ([a], [a])
divide xs = splitAt lhx xs
where
lhx = length xs `div` 2
primary :: Proxy "primary"
primary = Proxy
worker1 :: Proxy "worker1"
worker1 = Proxy
worker2 :: Proxy "worker2"
worker2 = Proxy
sort ::
KnownSymbol a =>
Proxy a ->
KnownSymbol b =>
Proxy b ->
KnownSymbol c =>
Proxy c ->
([Int] @ a) ->
Choreo IO ([Int] @ a)
sort a b c lst = do
condition <- a `locally` \unwrap -> do return $ length (unwrap lst) > 1
cond (a, condition) \case
True -> do
pivot <- a `locally` \unwrap -> do return $ length (unwrap lst) `div` 2
divided <- a `locally` \unwrap -> do return $ divide (unwrap lst)
l <- a `locally` \unwrap -> do return $ fst (unwrap divided)
r <- a `locally` \unwrap -> do return $ snd (unwrap divided)
l' <- (a, l) ~> b
r' <- (a, r) ~> c
ls' <- sort b c a l'
rs' <- sort c a b r'
merge a b c ls' rs'
False -> do
return lst
merge ::
KnownSymbol a =>
Proxy a ->
KnownSymbol b =>
Proxy b ->
KnownSymbol c =>
Proxy c ->
[Int] @ b ->
[Int] @ c ->
Choreo IO ([Int] @ a)
merge a b c lhs rhs = do
lhsHasElements <- b `locally` \unwrap -> do return $ not (null (unwrap lhs))
cond (b, lhsHasElements) \case
True -> do
rhsHasElements <- c `locally` \unwrap -> do return $ not (null (unwrap rhs))
cond (c, rhsHasElements) \case
True -> do
rhsHeadAtC <- c `locally` \unwrap -> do return $ head (unwrap rhs)
rhsHeadAtB <- (c, rhsHeadAtC) ~> b
takeLhs <- b `locally` \unwrap -> do return $ head (unwrap lhs) <= unwrap rhsHeadAtB
cond (b, takeLhs) \case
True -> do
-- take (head lhs) and merge the rest
lhs' <- b `locally` \unwrap -> do return $ tail (unwrap lhs)
merged <- merge a b c lhs' rhs
lhsHeadAtB <- b `locally` \unwrap -> do return $ head (unwrap lhs)
lhsHeadAtA <- (b, lhsHeadAtB) ~> a
a `locally` \unwrap -> do return $ unwrap lhsHeadAtA : unwrap merged
False -> do
-- take (head rhs) and merge the rest
rhs' <- c `locally` \unwrap -> do return $ tail (unwrap rhs)
merged <- merge a b c lhs rhs'
rhsHeadAtC <- c `locally` \unwrap -> do return $ head (unwrap rhs)
rhsHeadAtA <- (c, rhsHeadAtC) ~> a
a `locally` \unwrap -> do return $ unwrap rhsHeadAtA : unwrap merged
False -> do
(b, lhs) ~> a
False -> do
(c, rhs) ~> a
mainChoreo :: Choreo IO ()
mainChoreo = do
lst <- primary `locally` \unwrap -> do return [1, 6, 5, 3, 4, 2, 7, 8]
sorted <- sort primary worker1 worker2 lst
primary `locally` \unwrap -> do
print (unwrap sorted)
return ()
return ()
main :: IO ()
main = do
[loc] <- getArgs
case loc of
"primary" -> runChoreography config mainChoreo "primary"
"worker1" -> runChoreography config mainChoreo "worker1"
"worker2" -> runChoreography config mainChoreo "worker2"
return ()
where
config =
mkHttpConfig
[ ("primary", ("localhost", 3000)),
("worker1", ("localhost", 4000)),
("worker2", ("localhost", 5000))
]