;; trycatch.hs — try pattern: branch on Left/Right (Phase 16 conformance).

(define
  hk-trycatch-source
  "parseInt :: String -> IO Int
parseInt \"zero\" = return 0
parseInt \"one\"  = return 1
parseInt \"two\"  = return 2
parseInt s = throwIO (SomeException (\"unknown: \" ++ s))

describe :: Either SomeException Int -> String
describe (Right v) = \"got \" ++ show v
describe (Left (SomeException m)) = \"err: \" ++ m

trial :: String -> IO String
trial s = do
  r <- try (parseInt s)
  return (describe r)

run3 :: String -> String -> String -> IO [String]
run3 a b c = do
  ra <- trial a
  rb <- trial b
  rc <- trial c
  return [ra, rb, rc]

")

(hk-test
  "trycatch.hs — Right branch"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source "main = trial \"one\"")))
  (list "IO" "got 1"))

(hk-test
  "trycatch.hs — Left branch with message"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source "main = trial \"banana\"")))
  (list "IO" "err: unknown: banana"))

(hk-test
  "trycatch.hs — chain over three inputs, all good"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source "main = run3 \"zero\" \"one\" \"two\"")))
  (list "IO"
    (list ":" "got 0"
      (list ":" "got 1"
        (list ":" "got 2"
          (list "[]"))))))

(hk-test
  "trycatch.hs — chain over three inputs, mixed"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source "main = run3 \"zero\" \"qux\" \"two\"")))
  (list "IO"
    (list ":" "got 0"
      (list ":" "err: unknown: qux"
        (list ":" "got 2"
          (list "[]"))))))

(hk-test
  "trycatch.hs — Left from throwIO carries message"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source
        "main = do { r <- try (throwIO (SomeException \"explicit\")); return (describe r) }")))
  (list "IO" "err: explicit"))

(hk-test
  "trycatch.hs — Right preserves the int"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source
        "main = do { r <- try (return 42); return (describe r) }")))
  (list "IO" "got 42"))

(hk-test
  "trycatch.hs — pattern-bind on Right inside do"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source
        "main = do { Right v <- try (parseInt \"two\"); return (v + 100) }")))
  (list "IO" 102))

(hk-test
  "trycatch.hs — handle alias on parseInt failure"
  (hk-deep-force
    (hk-run
      (str hk-trycatch-source
        "main = handle (\\(SomeException m) -> return (\"caught: \" ++ m)) (parseInt \"nope\" >>= (\\v -> return (show v)))")))
  (list "IO" "caught: unknown: nope"))
