unison/unison-src/tests/stream2.uu
2021-08-24 11:33:27 -07:00

82 lines
1.8 KiB
Plaintext

structural ability Emit a where
emit : a ->{Emit a} ()
structural type Stream e a r = Stream ('{e, Emit a} r)
use Stream Stream
use Optional None Some
use Universal ==
namespace Stream where
step :
(a ->{e} b) ->
Request {Emit a} r ->{e, Emit b} r
step f = cases
{r} -> r
{Emit.emit a -> k} ->
Emit.emit (f a)
handle k () with step f
-- map : (a -> b) -> Stream {e} a r -> Stream {e} b r
map : (a ->{e} b)
-> Stream {e} a r
-> Stream {e} b r
map f s = Stream ' handle run s with step f
run : Stream e a r ->{e, Emit a} r
run = cases Stream c -> !c
---
-- run' = cases Stream s -> s
-- unfold : s -> (s ->{} Optional (a, s)) -> Stream e a ()
unfold s f =
step = cases
None -> ()
Some (a, s) -> emit a
step s
Stream '(step s)
(++) : Stream {e} a r -> Stream {e} a r -> Stream {e} a r
s1 ++ s2 = Stream '(run' s1 !! run' s2)
from : Nat -> Stream e Nat ()
from n = unfold n (n -> Some (n, n + 1))
-- take : Nat -> Stream {} a () -> Stream {} a ()
take n s =
step n = cases
{Emit.emit a -> k} ->
if n Nat.== 0 then ()
else
Emit.emit a
handle k () with step (n `drop` 1)
{r} -> ()
Stream ' handle run s with step n
---
-- toSeq : Stream {e} a r ->{e} [a]
toSeq s =
step acc = cases
{Emit.emit a -> k} -> handle k () with step (acc `snoc` a)
{_} -> acc
handle run s with step []
fromSeq : [a] -> Stream e a ()
fromSeq a =
step a = match List.at 0 a with
None -> None
Some h -> Some (h, drop 1 a)
unfold a step
> toSeq (Stream.take 7 (Stream.map (x -> x + 10) (from 0)))
-- > toSeq (Stream.fromSeq [1,2,3] ++ Stream.fromSeq [4,5,6])
-- > toSeq (Stream.take 20 (from 0))
-- run two thunks in sequence
a !! b =
!a
!b