An elevator example. > import Control.Hasim > import Control.Monad.State Suppose we have an elevator in a building with two floors, 0 and 1. Passengers arrive at floor 0, and enter the elevator if possible. > newtype Passenger = P Int > > simdef = do > p1 <- mkProcess "elevator" [] > p2 <- mkProcess "passenger generator" 0 > p3 <- mkAnonProcess > p1 `setAction` elevator p3 > p2 `setAction` generator p1 > p3 `setAction` counter The process p3 will act as a counter on floor 1. Define the behavior of the generator: > generator p1 = do > idx <- get > put (idx + 1) > wait 1 > sendBlock (P idx) p1 > generator p1 Define the behavior of the elevator: > elevator p3 = do > p <- receive > withoutInterruptions \$ do > wait 0.3 -- The time that it takes to go to floor 1 > sendBlock p p3 > wait 0.3 -- The time that it takes to go to floor 0 > elevator p3 Define the behavior of the counter: > counter = do > p <- receive > let (P idx) = p > t <- getTime > liftIO \$ putStrLn \$ "Passenger " ++ show idx ++ " arrived at " ++ show t > counter Run the simulation: > main = createSimulation simdef >>= runSimulation We could adapt the behavior of the elevator, to wait for 1.5, take as many passengers as possible, and then go to floor 1. > elevator2 p3 = do > t <- getTime > liftIO \$ putStrLn \$ "I am waiting until t = " ++ show (t+1.5) > withAcceptor (\pkt -> Parallel (pkt:)) (wait 1.5) > ps <- get > when (null ps) (withAcceptor (\pkt -> Interrupt (modify (pkt:))) waitForever) > withoutInterruptions \$ do > ps <- get > liftIO \$ putStrLn "Elevator is going up." > wait 0.3 > mapM_ (\p -> sendBlock p p3) ps > put [] > wait 0.3 > elevator2 p3 Create a new simulation definition using this function: > simdef2 = do > p1 <- mkProcess "elevator" [] > p2 <- mkProcess "passenger generator" 0 > p3 <- mkAnonProcess > p1 `setAction` elevator2 p3 > p2 `setAction` generator p1 > p3 `setAction` counter > > main2 = createSimulation simdef2 >>= runSimulation