#include "BUCASCS320.hats"
datatype seq (a:t@ype) = Nil (a) of () | Cons (a) of (a, () -<cloref1> seq a)
exception Empty of ()
exception Subscript of ()
fun{a:t@ype} hd (xs: seq a): a = case+ xs of
| Cons (x, _) => x | Nil () => $raise Empty ()
fun{a:t@ype} tl (xs: seq a): seq a = case+ xs of
| Cons (_, fxs) => fxs () | Nil () => $raise Empty ()
fun{a:t@ype} cons (x: a , xs: seq a): seq a = Cons (x, lam () => xs)
fun from (k: int): seq int = Cons (k, lam () => from (k+1))
fun{a:t@ype} take (xs: seq a, n: int): list0 a =
if n = 0 then list0_nil ()
else begin case+ xs of | Nil () => $raise Subscript ()
| Cons (x, fxs) => list0_cons (x, take (fxs (), n-1))
end
fun{a:t@ype} nth (xs: seq a, n: int): a = case+ xs of
| Cons (x, fxs) => if n = 0 then x else nth (fxs (), n-1)
| Nil () => $raise Subscript ()
fun{a,b:t@ype} map
(xs: seq a, f: a -<cloref1> b): seq b = case+ xs of
| Cons (x, fxs) => Cons (f x, lam () => map (fxs (), f))
| Nil () => Nil ()
fun{a:t@ype} filter (pred: a -<cloref1> bool, xs: seq a): seq a =
case+ xs of
| Cons (x, fxs) => begin
if pred x then Cons (x, lam () => filter (pred, fxs ())) else filter (pred, fxs ())
end | Nil () => Nil ()
fun sift (p: int, xs: seq int): seq int =
filter<int> (lam (x) => x mod p <> 0, xs)
fun sieve (xs: seq int): seq int = let
val- Cons (x, fxs) = xs in Cons (x, lam () => sieve (sift (x, fxs ())))
end
val primes = sieve (from 2)
val p5000 = nth (primes, 5000-1)
val () = printf ("p5000 = %i", @(p5000))
val () = print_newline ()
val () = print ("Testing memoization: a long pause shoule be experienced!")
val () = print_newline ()
val p5000 = nth (primes, 5000-1)
val () = printf ("p5000 = %i", @(p5000))
val () = print_newline ()
implement main () = ()