{-  
    COMS 4995: Parallel Functional Programming, Fall 2025
    Quiz 7: Par monad

    1. Close all devices (phone/laptop, etc). Make sure you have an index card to write on, and a pen/pencil.

    2. PLEASE WRITE YOUR NAME AND UNI AS LEGIBLY AS POSSIBLE

    3. Read the quiz question below, and write your answer on your index card. CIRCLE YOUR ANSWER.

    4. Turn in your card at the table in the front of the room.
-}

import Control.Monad.Par

parDataflow :: Int -> Par Int
parDataflow input = do
    a <- new
    b <- new
    c <- new
    fork $ do x <- get b
              put c (x + 2)
    fork $ do y <- get a
              put b (y * 5)
    fork $ put a input
    get c

main :: IO ()
main = print $ runPar $ parDataflow 3

{- QUESTION:
What does this program print when run?
You may assume it compiles (with -threaded and -rtsopts, run with +RTS -N4).
You should NOT assume it is free from runtime errors.
If it will have a runtime error, write "runtime error".
-}

-- ANSWER: 17

-- EXPLANATION:
-- We print the value which is `put` to the IVar `c` as a result of the parallel computation.
-- The dataflow dependencies in the spawned processes form a straight line:
--   a
--   |
--   b
--   |
--   c
-- This dataflow has no deadlock, so there's no runtime error.
-- Due to the order of operations, the result is (3 * 5) + 2.