Skip to content

Instantly share code, notes, and snippets.

@Azhng
Last active March 1, 2019 05:38
Show Gist options
  • Save Azhng/a422e7a8c5e1a44ba0cd046b7aebdf15 to your computer and use it in GitHub Desktop.
Save Azhng/a422e7a8c5e1a44ba0cd046b7aebdf15 to your computer and use it in GitHub Desktop.
signature STREAM = sig
type 'a stream
val mkseq: 'a -> ('a -> 'a) -> 'a stream
val car: 'a stream -> 'a
val cdr: 'a stream -> 'a stream
val nth: 'a stream -> int -> 'a
val toList: 'a stream -> int -> 'a list
end
structure Seq :> STREAM = struct
datatype 'a elem = Materialized of 'a | Promise of unit -> 'a
datatype 'a stream = Stream of 'a elem list * ('a -> 'a)
exception WTF
fun mkseq z succ =
let
val next = fn () => succ z
in
Stream ([Materialized z, Promise next], succ)
end
fun car (Stream (((Materialized x)::xs), _)) = x
| car _ = raise WTF
fun cdr (Stream (((Materialized x)::xs), succ)) =
let
val cur = hd xs
in
case cur of
Promise p =>
let
val newVal = p()
in
Stream ([Materialized newVal, (Promise (fn () => succ newVal))], succ)
end
| _ => raise WTF
end
| cdr _ = raise WTF
fun nth s 0 = car s
| nth s n = nth (cdr s) (n - 1)
fun toList s 0 = []
| toList s n = [(car s)] @ toList (cdr s) (n - 1)
end
(* Test code *)
val seqNum = Seq.mkseq 0 (fn x => x + 1)
val seqStr = Seq.mkseq "a" (fn x => x ^ (String.extract (x, 0, SOME 1)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment