Skip to content

Instantly share code, notes, and snippets.

@chiroptical
Created June 26, 2020 02:05
Show Gist options
  • Save chiroptical/9471ba07cb3bdb44a4e614727db4ccad to your computer and use it in GitHub Desktop.
Save chiroptical/9471ba07cb3bdb44a4e614727db4ccad to your computer and use it in GitHub Desktop.
Stream in Unison
Stream.sum : '{Stream Nat} () -> Nat
Stream.sum = Stream.foldLeft (+) 0
> Stream.sum '(Stream.range 0 10)
ability Stream e where
emit : e ->{Stream e} ()
Stream.range : Nat -> Nat ->{Stream Nat} ()
Stream.range n m =
if n >= m then ()
else
emit n
Stream.range (n + 1) m
Stream.toList : '{Stream a} () -> [a]
Stream.toList stream =
h : [a] -> Request {Stream a} () -> [a]
h acc = cases
{Stream.emit e -> resume} ->
handle !resume with h (acc :+ e)
_ -> acc
handle !stream with h []
-- > Stream.toList '(Stream.range 0 10)
-- Stream.sum : '{Stream Nat} () -> Nat
-- Stream.sum stream =
-- h : Nat -> Request {Stream Nat} () -> Nat
-- h acc = cases
-- {Stream.emit n -> resume} ->
-- handle !resume with h (acc + n)
-- _ -> acc
-- handle !stream with h 0
Stream.foldLeft : (b -> a -> b) -> b -> '{Stream a} () -> b
Stream.foldLeft f empty stream =
h : b -> Request {Stream a} () -> b
h acc = cases
{Stream.emit a -> resume} ->
handle !resume with h (f acc a)
_ -> acc
handle !stream with h empty
prependStream : a ->{Stream a} () ->{Stream a} ()
prependStream val stream =
Stream.emit val
stream
Stream.map : (a -> b) -> '{Stream a} r -> '{Stream b} r
Stream.map f stream =
h : Request {Stream a} r -> {Stream b} r
h = cases
{Stream.emit x -> resume} ->
emit (f x)
handle !resume with h
{ u } -> u
'(handle !stream with h)
> Stream.toList (Stream.map (x -> x + 1) '(Stream.range 0 10))
Stream.filter : (a -> Boolean) -> '{Stream a} () -> '{Stream a} ()
Stream.filter pred stream =
h : Request {Stream a} () -> {Stream a} ()
h = cases
{Stream.emit a -> resume} ->
if pred a then emit a else ()
handle !resume with h
{u} -> u
'(handle !stream with h)
> Stream.toList (Stream.filter (x -> x > 5) '(Stream.range 0 10))
Stream.take : Nat -> '{Stream a} () -> '{Stream a} ()
Stream.take n stream =
h : Int -> Request {Stream a} () -> {Stream a} ()
h m req = match (m, req) with
(+0, {Stream.emit x -> resume}) ->
emit x
(o, {Stream.emit x -> resume}) ->
emit x
handle !resume with h (o - +1)
(_, {u}) -> u
'(handle !stream with h (toInt n))
> Stream.toList (Stream.take 5 '(Stream.range 0 10))
Stream.terminated : '{Stream a} () -> '{Stream (Optional a)} ()
Stream.terminated stream =
h : Request {Stream a} () -> {Stream (Optional a)} ()
h = cases
{Stream.emit a -> resume} ->
emit (Some a)
handle !resume with h
{u} ->
emit None
u
'(handle !stream with h)
> Stream.toList (Stream.terminated '(Stream.range 0 10))
program : '{IO} ()
program = 'let
greet "Chexxor"
printLine (foldl (++) "" (Stream.toList (Stream.map toText '(Stream.range 0 10))))
greet : Text -> {IO} ()
greet name =
printLine ("Hello there, " ++ name)
printLine ("Hello there, " ++ name)
frobnicate : (Nat ->{IO} Nat) -> Nat ->{IO, Stream Text} Nat
frobnicate transmogrify i =
emit ("Frobnicating: " ++ Nat.toText i)
n = transmogrify i * transmogrify (i*2)
emit ("I think that worked! " ++ Nat.toText n)
n
transmogrificate : Nat ->{IO} Nat
transmogrificate = (x -> x * 11)
logToStdOut : '{IO, Stream Text} a -> {IO} a
logToStdOut stream =
h : Request {IO, Stream Text} a -> {IO} a
h = cases
{Stream.emit a -> resume} ->
printLine a
handle !resume with h
{u} ->
u
handle !stream with h
interpretation : '{IO} ()
interpretation = 'let
printLine (Nat.toText (logToStdOut '(frobnicate transmogrificate 1)))
ability Ask a where
ask : a
Ask.provide : a -> '{Ask a} r -> r
Ask.provide a asker =
h = cases
{r} ->
r
{Ask.ask -> resume} ->
handle resume a with h
handle !asker with h
> Ask.provide 10 '(1 + Ask.ask + Ask.ask)
> Ask.provide "Bob" '("Hello there, " ++ Ask.ask)
Stream.pipe : '{Stream a} () -> '{Ask a, Stream b} r -> '{Stream b} ()
Stream.pipe s f =
h ss = cases
{_} -> ()
{Ask.ask -> resumeF} ->
handle !ss with cases
{_} -> ()
{Stream.emit a -> resumeS} ->
handle resumeF a with h resumeS
{Stream.emit b -> resumeF} ->
emit b
handle resumeF () with h ss
'(handle !f with h s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment