;; counter.hs — IORef-backed mutable counter (Phase 15 conformance). (define hk-counter-source "import qualified Data.IORef as IORef\n\ncount :: IORef Int -> Int -> IO ()\ncount r 0 = return ()\ncount r n = do\n IORef.modifyIORef r (\\x -> x + 1)\n count r (n - 1)\n\ncountBy :: IORef Int -> Int -> Int -> IO ()\ncountBy r step 0 = return ()\ncountBy r step n = do\n IORef.modifyIORef r (\\x -> x + step)\n countBy r step (n - 1)\n\nnewCounter :: Int -> IO (IORef Int)\nnewCounter v = IORef.newIORef v\n\nbumpAndRead :: IORef Int -> IO Int\nbumpAndRead r = do\n IORef.modifyIORef r (\\x -> x + 1)\n IORef.readIORef r\n\n") (hk-test "counter.hs — start at 0, count 5 ⇒ 5" (hk-deep-force (hk-run (str hk-counter-source "main = do { r <- newCounter 0; count r 5; v <- IORef.readIORef r; return v }"))) (list "IO" 5)) (hk-test "counter.hs — start at 100, count 10 ⇒ 110" (hk-deep-force (hk-run (str hk-counter-source "main = do { r <- newCounter 100; count r 10; v <- IORef.readIORef r; return v }"))) (list "IO" 110)) (hk-test "counter.hs — countBy step 5, n 4 ⇒ 20" (hk-deep-force (hk-run (str hk-counter-source "main = do { r <- newCounter 0; countBy r 5 4; v <- IORef.readIORef r; return v }"))) (list "IO" 20)) (hk-test "counter.hs — bumpAndRead returns updated value" (hk-deep-force (hk-run (str hk-counter-source "main = do { r <- newCounter 41; bumpAndRead r }"))) (list "IO" 42)) (hk-test "counter.hs — count then countBy compose" (hk-deep-force (hk-run (str hk-counter-source "main = do { r <- newCounter 0; count r 3; countBy r 10 2; v <- IORef.readIORef r; return v }"))) (list "IO" 23)) (hk-test "counter.hs — two independent counters" (hk-deep-force (hk-run (str hk-counter-source "main = do { a <- newCounter 0; b <- newCounter 0; count a 7; countBy b 100 2; va <- IORef.readIORef a; vb <- IORef.readIORef b; return (va + vb) }"))) (list "IO" 207)) (hk-test "counter.hs — modifyIORef' (strict) variant" (hk-deep-force (hk-run (str hk-counter-source "tick r 0 = return ()\ntick r n = do { IORef.modifyIORef' r (\\x -> x + 1); tick r (n - 1) }\nmain = do { r <- newCounter 0; tick r 50; v <- IORef.readIORef r; return v }"))) (list "IO" 50))