;; fib.hs — infinite Fibonacci stream classic program.
;;
;; The canonical artefact lives at lib/haskell/tests/programs/fib.hs.
;; The source is mirrored here as an SX string because the evaluator
;; doesn't have read-file in the default env. If you change one, keep
;; the other in sync — there's a runner-level cross-check against the
;; expected first-15 list.

(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-fib-source
  "zipPlus (x:xs) (y:ys) = x + y : zipPlus xs ys
zipPlus _ _ = []
myFibs = 0 : 1 : zipPlus myFibs (tail myFibs)
result = take 15 myFibs
")

(hk-test
  "fib.hs — first 15 Fibonacci numbers"
  (hk-as-list (hk-prog-val hk-fib-source "result"))
  (list 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377))

;; Spot-check that the user-defined zipPlus is also reachable
(hk-test
  "fib.hs — zipPlus is a multi-clause user fn"
  (hk-as-list
    (hk-prog-val
      (str hk-fib-source "extra = zipPlus [1, 2, 3] [10, 20, 30]\n")
      "extra"))
  (list 11 22 33))

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