#include "share/atspre_staload.hats"
datatype _stream (a:t@ype) =
| stream_nil (a) of ()
| stream_cons (a) of (a, lazy (_stream a))
#define nil stream_nil
#define :: stream_cons
typedef stream (a:t@ype) = lazy (_stream a)
extern fun {a:t@ype} interleave (stream a, stream a): stream a
extern fun {a,b:t@ype} map (stream a, a -> b): stream b
extern fun {a:t@ype} tabulate (int, int -> a): stream a
extern fun {a:t@ype} iterate (a, a -> a): stream a
extern fun {a:t@ype} transpose (stream (stream a)): stream (stream a)
extern fun {a:t@ype} show (stream a, int): void
extern fun {a:t@ype} show$f (a): void
implement show$f<int> (n) = let val _ = print_int n in print_string "::" end
implement {a} show (xs, n) =
if n > 0
then
case+ !xs of
| x :: xs => let val _ = show$f x in show (xs, n-1) end
| nil () => println! "nil"
else
println! "nil"
implement {a} interleave (xs, ys) = $delay (
case+ !xs of
| nil () => !ys
| x :: xs => x :: interleave (ys, xs)
)
implement {a,b} map (xs, f) = $delay (
case+ !xs of
| nil () => nil ()
| x :: xs => f (x) :: map (xs, f)
)
implement {a} tabulate (n, f) = $delay (
f (n) :: tabulate (n+1, f)
)
implement {a} iterate (n, f) = $delay (
n :: iterate (f (n), f)
)
implement {a} transpose (xss) = $delay (
let
val heads = map (xss, lam xs => let val- x :: _ = !xs in x end)
val tails = map (xss, lam xs => let val- _ :: xs = !xs in xs end)
in
heads :: transpose (tails)
end
)
implement main0 () = () where {
val xs = tabulate (0, lam x => x)
val _ = show (xs, 10)
val ys = iterate<int> (0, lam x => x+2)
val _ = show (ys, 10)
val _ = show (interleave (xs, ys), 20)
val xss = iterate<stream int> (tabulate (0, lam x => x), lam xs => map (xs, lam x => x * 2))
implement show$f<stream(int)> (xs) = show (xs, 10)
val _ = show (xss, 10)
val _ = show (transpose xss, 10)
}