;; safediv.hs — safe division using catch (Phase 16 conformance). (define hk-safediv-source "safeDiv :: Int -> Int -> IO Int safeDiv _ 0 = throwIO (SomeException \"division by zero\") safeDiv x y = return (x `div` y) guarded :: Int -> Int -> IO Int guarded x y = catch (safeDiv x y) (\\(SomeException _) -> return 0) reason :: Int -> Int -> IO String reason x y = catch (safeDiv x y `seq` return \"ok\") (\\(SomeException m) -> return m) bothBranches :: Int -> Int -> IO Int bothBranches x y = do v <- catch (safeDiv x y) (\\(SomeException _) -> return (-1)) return (v + 100) ") (hk-test "safediv.hs — divide by non-zero" (hk-deep-force (hk-run (str hk-safediv-source "main = guarded 10 2"))) (list "IO" 5)) (hk-test "safediv.hs — divide by zero returns 0" (hk-deep-force (hk-run (str hk-safediv-source "main = guarded 10 0"))) (list "IO" 0)) (hk-test "safediv.hs — divide by zero — reason captured" (hk-deep-force (hk-run (str hk-safediv-source "main = catch (safeDiv 1 0) (\\(SomeException m) -> return 0) >> reason 1 0"))) (list "IO" "division by zero")) (hk-test "safediv.hs — bothBranches success path" (hk-deep-force (hk-run (str hk-safediv-source "main = bothBranches 8 2"))) (list "IO" 104)) (hk-test "safediv.hs — bothBranches failure path" (hk-deep-force (hk-run (str hk-safediv-source "main = bothBranches 8 0"))) (list "IO" 99)) (hk-test "safediv.hs — chained safeDiv with catch" (hk-deep-force (hk-run (str hk-safediv-source "main = do { a <- guarded 20 4; b <- guarded 7 0; return (a + b) }"))) (list "IO" 5)) (hk-test "safediv.hs — try then bind through Either" (hk-deep-force (hk-run (str hk-safediv-source "main = do { r <- try (safeDiv 1 0); case r of { Right v -> return v; Left (SomeException m) -> return 999 } }"))) (list "IO" 999)) (hk-test "safediv.hs — handle (flip catch)" (hk-deep-force (hk-run (str hk-safediv-source "main = handle (\\(SomeException _) -> return 0) (safeDiv 5 0)"))) (list "IO" 0))