;; powers.hs — integer exponentiation and powers-of-2 checks. (define hk-prog-val (fn (src name) (hk-deep-force (get (hk-eval-program (hk-core src)) name)))) (define hk-as-list (fn (xs) (cond ((and (list? xs) (= (first xs) "[]")) (list)) ((and (list? xs) (= (first xs) ":")) (cons (nth xs 1) (hk-as-list (nth xs 2)))) (:else xs)))) (define hk-pow-src "pow _ 0 = 1\npow base n = base * pow base (n - 1)\n\npowers base k = map (pow base) [0..k]\n\nisPowerOf2 n\n | n <= 0 = False\n | n == 1 = True\n | otherwise = n `mod` 2 == 0 && isPowerOf2 (n `div` 2)\n\nlog2 1 = 0\nlog2 n = 1 + log2 (n `div` 2)\n") (hk-test "pow 2 0 = 1" (hk-prog-val (str hk-pow-src "r = pow 2 0\n") "r") 1) (hk-test "pow 2 1 = 2" (hk-prog-val (str hk-pow-src "r = pow 2 1\n") "r") 2) (hk-test "pow 2 8 = 256" (hk-prog-val (str hk-pow-src "r = pow 2 8\n") "r") 256) (hk-test "pow 3 4 = 81" (hk-prog-val (str hk-pow-src "r = pow 3 4\n") "r") 81) (hk-test "pow 10 3 = 1000" (hk-prog-val (str hk-pow-src "r = pow 10 3\n") "r") 1000) (hk-test "powers 2 4 = [1,2,4,8,16]" (hk-as-list (hk-prog-val (str hk-pow-src "r = powers 2 4\n") "r")) (list 1 2 4 8 16)) (hk-test "powers 3 3 = [1,3,9,27]" (hk-as-list (hk-prog-val (str hk-pow-src "r = powers 3 3\n") "r")) (list 1 3 9 27)) (hk-test "isPowerOf2 1 = True" (hk-prog-val (str hk-pow-src "r = isPowerOf2 1\n") "r") (list "True")) (hk-test "isPowerOf2 8 = True" (hk-prog-val (str hk-pow-src "r = isPowerOf2 8\n") "r") (list "True")) (hk-test "isPowerOf2 6 = False" (hk-prog-val (str hk-pow-src "r = isPowerOf2 6\n") "r") (list "False")) (hk-test "isPowerOf2 0 = False" (hk-prog-val (str hk-pow-src "r = isPowerOf2 0\n") "r") (list "False")) (hk-test "log2 1 = 0" (hk-prog-val (str hk-pow-src "r = log2 1\n") "r") 0) (hk-test "log2 8 = 3" (hk-prog-val (str hk-pow-src "r = log2 8\n") "r") 3) (hk-test "log2 1024 = 10" (hk-prog-val (str hk-pow-src "r = log2 1024\n") "r") 10) {:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail}