;; class-defaults.sx — Phase 13: class default method implementations.

;; ── Eq default: myNeq derived from myEq via `not (myEq x y)` ──
(define
  hk-myeq-source
  "class MyEq a where\n  myEq :: a -> a -> Bool\n  myNeq :: a -> a -> Bool\n  myNeq x y = not (myEq x y)\ninstance MyEq Int where\n  myEq x y = x == y\n")

(hk-test
  "Eq default: myNeq 3 5 = True (no explicit myNeq in instance)"
  (hk-deep-force (hk-run (str hk-myeq-source "main = myNeq 3 5\n")))
  (list "True"))

(hk-test
  "Eq default: myNeq 3 3 = False"
  (hk-deep-force (hk-run (str hk-myeq-source "main = myNeq 3 3\n")))
  (list "False"))

(hk-test
  "Eq default: myEq still works in same instance"
  (hk-deep-force (hk-run (str hk-myeq-source "main = myEq 7 7\n")))
  (list "True"))

;; ── Override path: instance can still provide the method explicitly. ──
(hk-test
  "Default override: instance-provided beats class default"
  (hk-deep-force
    (hk-run
      "class Hi a where\n  greet :: a -> String\n  greet x = \"default\"\ninstance Hi Bool where\n  greet x = \"override\"\nmain = greet True"))
  "override")

(hk-test
  "Default fallback: empty instance picks default"
  (hk-deep-force
    (hk-run
      "class Hi a where\n  greet :: a -> String\n  greet x = \"default\"\ninstance Hi Bool where\nmain = greet True"))
  "default")

(define
  hk-myord-source
  "class MyOrd a where\n  myCmp :: a -> a -> Bool\n  myMax :: a -> a -> a\n  myMin :: a -> a -> a\n  myMax a b = if myCmp a b then a else b\n  myMin a b = if myCmp a b then b else a\ninstance MyOrd Int where\n  myCmp x y = x >= y\n")

(hk-test
  "Ord default: myMax 3 5 = 5"
  (hk-deep-force (hk-run (str hk-myord-source "main = myMax 3 5\n")))
  5)

(hk-test
  "Ord default: myMax 8 2 = 8"
  (hk-deep-force (hk-run (str hk-myord-source "main = myMax 8 2\n")))
  8)

(hk-test
  "Ord default: myMin 3 5 = 3"
  (hk-deep-force (hk-run (str hk-myord-source "main = myMin 3 5\n")))
  3)

(hk-test
  "Ord default: myMin 8 2 = 2"
  (hk-deep-force (hk-run (str hk-myord-source "main = myMin 8 2\n")))
  2)

(hk-test
  "Ord default: myMax of equals returns first"
  (hk-deep-force (hk-run (str hk-myord-source "main = myMax 4 4\n")))
  4)

(define
  hk-mynum-source
  "class MyNum a where\n  mySub :: a -> a -> a\n  myLt :: a -> a -> Bool\n  myNegate :: a -> a\n  myAbs :: a -> a\n  myNegate x = mySub (mySub x x) x\n  myAbs x = if myLt x (mySub x x) then myNegate x else x\ninstance MyNum Int where\n  mySub x y = x - y\n  myLt x y = x < y\n")

(hk-test
  "Num default: myNegate 5 = -5"
  (hk-deep-force (hk-run (str hk-mynum-source "main = myNegate 5\n")))
  -5)

(hk-test
  "Num default: myAbs (myNegate 7) = 7"
  (hk-deep-force (hk-run (str hk-mynum-source "main = myAbs (myNegate 7)\n")))
  7)

(hk-test
  "Num default: myAbs 9 = 9"
  (hk-deep-force (hk-run (str hk-mynum-source "main = myAbs 9\n")))
  9)

{:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail}
