diff options
Diffstat (limited to 'src/nbc/sequence.sml')
-rw-r--r-- | src/nbc/sequence.sml | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/nbc/sequence.sml b/src/nbc/sequence.sml new file mode 100644 index 0000000..73a3fbf --- /dev/null +++ b/src/nbc/sequence.sml @@ -0,0 +1,74 @@ +signature SEQUENCE = sig + type 'a t + val fold: ('a * 'b -> 'b) -> 'b -> 'a t -> 'b + val from: (unit -> 'a option) -> 'a t + val map: ('a -> 'b) -> 'a t -> 'b t + val app: ('a -> unit) -> 'a t -> unit + val fromArray: 'a array -> 'a t + val fromList: 'a list -> 'a t + val toList: 'a t -> 'a list + val toArray: 'a t -> 'a array +end + +structure Sequence :> SEQUENCE = struct + type 'a t = unit -> 'a option + fun fold f seed t = + let + fun loop x = + case t () of + NONE => x + | SOME y => loop (f (y, x)) + in + loop seed + end + fun from t = t + fun map f t = + fn () => ( + case t () of + NONE => NONE + | SOME x => SOME (f x) + ) + fun app f t = + let + fun loop () = + case t () of + NONE => () + | SOME x => ( + f x + ; loop () + ) + in + loop () + end + fun fromArray a = + let + val i = ref 0 + fun f () = + if !i >= Array.length a then NONE + else + SOME (Array.sub (a, !i)) + before i := !i + 1 + in + from f + end + fun fromList l = + let + val c = ref l + fun f () = + case !c of + x :: y => (c := y; SOME x) + | nil => NONE + in + from f + end + fun toList t = + let + fun loop l = + case t () of + NONE => rev l + | SOME x => loop (x :: l) + in + loop nil + end + fun toArray t = Array.fromList (toList t) +end |