Last active
March 1, 2019 05:38
-
-
Save Azhng/a422e7a8c5e1a44ba0cd046b7aebdf15 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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