;; 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}