[MLton-user] Stream Fusion

Vesa Karvonen vesa.a.j.k at gmail.com
Wed Sep 19 23:51:04 PDT 2007


On 5/8/07, Stephen Weeks <sweeks at sweeks.com> wrote:
> Another standard way to hide existentials is to use a ref cell hidden
> in a closure.
[...]
> datatype 'a step =
>    DONE
>  | GIVE of 'a
>  | SKIP
>
> datatype 'a t = T of unit -> 'a step
>
> val unfold : 's * ('s -> ('a * 's) option) -> 'a t =
>    fn (s, f) => let
>       val r = ref s
>    in T (fn () =>
>          case f (!r) of
>             NONE => DONE
>           | SOME (a, s) => (r := s; GIVE a))
>    end

[I meant to sent this note much earlier, but never got around to it.]

Note that this gives a different semantics.  A stream using the above
implementation is ephemeral and can be iterated (folded) only once.
Of course, in most cases one only wants to iterate a stream once.
However, it is possible to implement streams using a universal type
(http://mlton.org/UniversalType) and the universal type can be
implemented using either exceptions or refs and closures.

In fact, the Extended Basis library now includes a scaled down
implementation of streams using a universal type:

  http://mlton.org/cgi-bin/viewsvn.cgi/mltonlib/trunk/com/ssh/extended-basis/unstable/public/sequence/stream.sig?view=auto
  http://mlton.org/cgi-bin/viewsvn.cgi/mltonlib/trunk/com/ssh/extended-basis/unstable/detail/sequence/stream.sml?view=auto

The stream module implemented in the EB can be compiled with either a
ref+closure or exn based universal type.

-Vesa Karvonen



More information about the MLton-user mailing list