(* stream.sig *) (* streams *) signature STREAM = sig (* an infinite stream of values of type 'a *) type 'a stream (* make(x, f) creates the streams whose elements are #1(f x), #1(f(#2(f x))), #1(f(#2(f(#2(f x))))), ... *) val make : 'a * ('a -> 'b * 'a) -> 'b stream (* get stm returns (x, stm'), where x is the initial element of stm, and stm is the remaining elements this memoizes the result of running f on its state, so running get stm in the future will just look up the result get and the following functions may fail to return or raise exceptions, depending upon the behavior of the function f used to make the stream *) val get : 'a stream -> 'a * 'a stream (* takeToList(stm, n) returns nil if n < 0; otherwise, it returns the first n elements of stm *) val takeToList : 'a stream * int -> 'a list (* drop(stm, n) returns stm if n < 0; otherwise it gets the first n elements of stm, returning the resulting stream *) val drop : 'a stream * int -> 'a stream (* rangeToList(stm, n, m) returns nil if n <= 0 or m < n; otherwise it returns the list consisting of the n'th through the m'th elements of stm, counting from 1 *) val rangeToList : 'a stream * int * int -> 'a list end;