;; sieve.hs — lazy sieve of Eratosthenes.
;;
;; The canonical artefact lives at lib/haskell/tests/programs/sieve.hs.
;; Mirrored here as an SX string because the default eval env has no
;; read-file. Uses filter + backtick `mod` + lazy [2..] — all of which
;; are now wired in via Phase 3 + the mod/div additions to hk-binop.

(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-prog-val
  (fn
    (src name)
    (hk-deep-force (get (hk-eval-program (hk-core src)) name))))

(define
  hk-sieve-source
  "sieve (p:xs) = p : sieve (filter (\\x -> x `mod` p /= 0) xs)
sieve [] = []
primes = sieve [2..]
result = take 10 primes
")

(hk-test
  "sieve.hs — first 10 primes"
  (hk-as-list (hk-prog-val hk-sieve-source "result"))
  (list 2 3 5 7 11 13 17 19 23 29))

(hk-test
  "sieve.hs — 20th prime is 71"
  (nth
    (hk-as-list
      (hk-prog-val
        (str
          hk-sieve-source
          "result20 = take 20 primes\n")
        "result20"))
    19)
  71)

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