[MLton-user] Stream Fusion

Stephen Weeks sweeks at sweeks.com
Mon May 7 19:07:11 PDT 2007


Another standard way to hide existentials is to use a ref cell hidden
in a closure.  I tried that for fusion and MLton, quite
pleasantly, generates identical code as for the exn approach.

loop_25:
	fldL (0+((8*1)+(0*1)))(%ebp)
	fcomp %st(1)
	fnstsw %ax
	testw $0x500,%ax
	jnz L_2428
L_1114:
	fld %st
	faddL (globalReal64+((0*8)+(0*1)))
	fxch %st(1)
	fsqrt
	faddp %st, %st(2)
	jmp loop_25

SML code follows.

----------------------------------------------------------------------

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

val map : 'a t * ('a -> 'b) -> 'b t =
   fn (T g, f) =>
   T (fn () =>
         case g () of
            DONE => DONE
          | SKIP => SKIP
          | GIVE a => GIVE (f a))

val fold : 'a t * 'b * ('a * 'b -> 'b) -> 'b =
   fn (T g, b, f) => let
      fun loop b =
         case g () of
            DONE => b
          | GIVE a => loop (f (a, b))
          | SKIP => loop b
   in
      loop b
   end

val n = valOf (Real.fromString (hd (CommandLine.arguments ())))

fun pr r = print (Real.toString r ^ "\n")

val sum =
   fold (map
         (unfold (1.0, fn i => if i <= n then SOME (i, i+1.0) else NONE),
          Math.sqrt),
         0.0,
         op +)

val () = pr sum



More information about the MLton-user mailing list